bump product version to 4.2.0.1
[LibreOffice.git] / include / unotools / idhelper.hxx
blobe0f8fd3af8fd15d2581cf26556b18c8fd1062b21
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #ifndef INCLUDED_UNOTOOLS_IDHELPER_HXX
21 #define INCLUDED_UNOTOOLS_IDHELPER_HXX
23 #include <com/sun/star/uno/Sequence.hxx>
24 #include <com/sun/star/lang/XTypeProvider.hpp>
25 #include <osl/mutex.hxx>
26 #include <comphelper/stl_types.hxx>
27 #include <cppuhelper/typeprovider.hxx>
28 #include <tools/debug.hxx>
30 //.........................................................................
31 namespace utl
33 //.........................................................................
35 //=========================================================================
36 // to shorten some lines ...
37 typedef ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > TypeSequence;
39 // compare to Sequences of Types
40 struct TypeSequenceLess : public ::std::binary_function<TypeSequence, TypeSequence, bool>
42 public:
43 inline bool operator() (const TypeSequence& lhs, const TypeSequence& rhs) const
45 sal_Int32 nLengthLeft = lhs.getLength();
46 sal_Int32 nLengthRight = rhs.getLength();
48 // first check the two lengths
49 if (nLengthLeft < nLengthRight)
50 return sal_True;
51 if (nLengthLeft > nLengthRight)
52 return sal_False;
54 // both sequences have the same length -> check the type names
55 const ::com::sun::star::uno::Type* pTypesLeft = lhs.getConstArray();
56 const ::com::sun::star::uno::Type* pTypesRight = rhs.getConstArray();
57 for (sal_Int32 i=0; i<nLengthLeft; ++i, ++pTypesLeft, ++pTypesRight)
59 sal_Int32 nTypeNameCompare = pTypesLeft->getTypeName().compareTo(pTypesRight->getTypeName());
60 if (nTypeNameCompare < 0)
61 return sal_True;
62 if (nTypeNameCompare > 0)
63 return sal_False;
66 // both sequences are equal ...
67 return sal_False;
71 // declare the map
72 DECLARE_STL_MAP ( TypeSequence,
73 ::cppu::OImplementationId,
74 TypeSequenceLess,
75 MapType2Id
78 //.........................................................................
79 } // namespace utl
80 //.........................................................................
82 //=========================================================================
83 /** defines a helper class for implementing the XTypeProvider::getImplementationId.
84 it maps sequences of ::com::sun::star::uno::Type to implementation ids
85 (which means sequences of bytes).<BR>
86 As there is no possibility to determine the time where the id's are no longer
87 needed (e.g. because the last instance of the class using this mechanism died)
88 the helper is "refcounted", i.e. there are acquire and release methods.
89 To simplify this there is a class classname##Ref which you may want to
90 use as an member of your classes.
91 <BR><BR>
92 As we don't want a global helper class which handles implementation id's
93 of components from all over the office (supposing somebody want's to use this :)
94 this is only a define. Wherever you have a "closed" area (which is small enough
95 and large enough :), see below) where diffenrent components want to use an id helper,
96 define your own one with this macro.<BR>
97 The more classes use this helper, the later redundant map entries will be
98 cleared. The less classes use it, the earlier map entries which may have
99 been reused will be cleared.
101 #define DECLARE_IMPLEMENTATIONID_HELPER(_namespace, classname) \
102 namespace _namespace { \
103 class classname \
105 friend class classname##Ref; \
107 static sal_Int32 s_nReferenced; \
108 static void* s_pMap; \
110 static ::osl::Mutex s_aMutex; \
112 public: \
113 static void acquire(); \
114 static void release(); \
116 static ::com::sun::star::uno::Sequence< sal_Int8 > getImplementationId( \
117 const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type >& _rTypes); \
119 private: \
120 static void implCreateMap(); \
122 classname() { } \
123 }; \
125 /*=======================================================================*/ \
126 class classname##Ref \
128 public: \
129 classname##Ref() { classname::acquire(); } \
130 ~classname##Ref() { classname::release(); } \
131 }; \
133 } /* _namespace */ \
136 /** implement an id helper
138 #define IMPLEMENT_IMPLEMENTATIONID_HELPER(_namespace, classname) \
139 namespace _namespace { \
141 /*=======================================================================*/ \
143 sal_Int32 classname::s_nReferenced(0); \
144 void* classname::s_pMap = NULL; \
145 ::osl::Mutex classname::s_aMutex; \
147 /*-----------------------------------------------------------------------*/ \
148 void classname::acquire() \
150 ::osl::MutexGuard aGuard(s_aMutex); \
151 ++s_nReferenced; \
154 /*-----------------------------------------------------------------------*/ \
155 void classname::release() \
157 ::osl::MutexGuard aGuard(s_aMutex); \
158 if (!--s_nReferenced) \
160 delete static_cast< ::utl::MapType2Id *>( s_pMap ); \
161 s_pMap = NULL; \
165 /*-----------------------------------------------------------------------*/ \
166 ::com::sun::star::uno::Sequence< sal_Int8 > classname::getImplementationId( \
167 const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type >& _rTypes) \
169 ::osl::MutexGuard aGuard(s_aMutex); \
170 DBG_ASSERT(s_nReferenced, \
171 "classname::getImplementationId : you need to hold a reference to this class in order to use it !"); \
172 /* give the calling class a member of type classname##Ref and all is fine .... */ \
174 implCreateMap(); \
176 ::utl::MapType2Id* pMap = static_cast< ::utl::MapType2Id *>(s_pMap); \
178 ::cppu::OImplementationId& rId = (*pMap)[_rTypes]; \
179 /* this will create an entry for the given type sequence, if necessary */ \
181 return rId.getImplementationId(); \
184 /*-----------------------------------------------------------------------*/ \
185 void classname::implCreateMap() \
187 if (s_pMap) \
188 return; \
189 s_pMap = new ::utl::MapType2Id(); \
193 } /* _namespace */ \
197 #endif // INCLUDED_UNOTOOLS_IDHELPER_HXX
199 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */