1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 #ifndef _CPPUHELPER_IMPLBASE_HXX_ 24 #define _CPPUHELPER_IMPLBASE_HXX_ 25 26 #include <osl/mutex.hxx> 27 #include <cppuhelper/weak.hxx> 28 #include <cppuhelper/weakagg.hxx> 29 #include <rtl/instance.hxx> 30 31 #include <com/sun/star/lang/XTypeProvider.hpp> 32 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 33 34 #include "cppuhelper/cppuhelperdllapi.h" 35 36 /* This header should not be used anymore. 37 @deprecated 38 */ 39 40 namespace cppu 41 { 42 43 /** Struct used for inline template implementation helpers: type entries. 44 Not for plublic use. 45 @internal 46 */ 47 struct Type_Offset 48 { 49 /** binary offset of vtable pointer from object base 50 */ 51 sal_Int32 nOffset; 52 /** interface type description of interface entry 53 */ 54 typelib_InterfaceTypeDescription * pTD; 55 }; 56 /** Struct used for inline template implementation helpers: class data of implementation. 57 Not for plublic use. 58 @internal 59 */ 60 struct CPPUHELPER_DLLPUBLIC ClassDataBase 61 { 62 /** determines whether the class data has been statically initialized 63 */ 64 sal_Bool bOffsetsInit; 65 /** length of static array ClassDataN 66 */ 67 sal_Int32 nType2Offset; 68 69 /** class code determines which standard types are supported (and returned on 70 com.sun.star.lang.XTypeProvider::getTypes()) by the helper: 71 72 - 1 -- com.sun.star.uno.XWeak 73 - 2 -- com.sun.star.uno.XWeak, com.sun.star.uno.XAggregation 74 - 3 -- com.sun.star.uno.XWeak, com.sun.star.uno.XAggregation, com.sun.star.lang.XComponent 75 - 4 -- com.sun.star.uno.XWeak, com.sun.star.lang.XComponent 76 */ 77 sal_Int32 nClassCode; 78 79 /** pointer to types sequence (com.sun.star.lang.XTypeProvider) 80 */ 81 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > * pTypes; 82 /** pointer to class id (com.sun.star.lang.XTypeProvider) 83 */ 84 ::com::sun::star::uno::Sequence< sal_Int8 > * pId; 85 86 /** def ctor 87 */ 88 ClassDataBase() SAL_THROW( () ); 89 /** class code ctor 90 91 @param nClassCode class code, see ClassDataBase::nClassCode 92 */ 93 ClassDataBase( sal_Int32 nClassCode ) SAL_THROW( () ); 94 /** dtor 95 */ 96 ~ClassDataBase() SAL_THROW( () ); 97 }; 98 /** Struct used for inline template implementation helpers: 99 There will be versions of this struct with varying arType2Offset[] array sizes, each of which 100 is binary compatible with this one to be casted and used uniform. The size of the varying array 101 is set in ClassDataBase::nType2Offset (base class). 102 Not for plublic use. 103 @internal 104 */ 105 struct CPPUHELPER_DLLPUBLIC ClassData : public ClassDataBase 106 { 107 /** type entries array 108 */ 109 Type_Offset arType2Offset[1]; 110 111 /** init call for supporting com.sun.star.lang.XTypeProvider 112 */ 113 void SAL_CALL initTypeProvider() SAL_THROW( () ); 114 /** initial writing type offsets for vtables 115 116 @param rType type of interface 117 @param nOffset offset to vtable entry 118 */ 119 void SAL_CALL writeTypeOffset( const ::com::sun::star::uno::Type & rType, sal_Int32 nOffset ) 120 SAL_THROW( () ); 121 122 /** Queries for an interface. 123 124 @param rType demanded interface type 125 @pBase base this pointer related when writing type offsets (writeTypeOffset()) 126 @return demanded interface or empty any 127 */ 128 ::com::sun::star::uno::Any SAL_CALL query( 129 const ::com::sun::star::uno::Type & rType, ::com::sun::star::lang::XTypeProvider * pBase ) 130 SAL_THROW( () ); 131 /** Gets the types for supporting com.sun.star.lang.XTypeProvider 132 133 @return sequence of types supported 134 */ 135 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes() 136 SAL_THROW( () ); 137 /** Gets the class id of implemtation supporting com.sun.star.lang.XTypeProvider 138 139 @return class identifier (sequence< byte >) 140 */ 141 ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() 142 SAL_THROW( () ); 143 }; 144 145 /** Shared mutex for implementation helper initialization. 146 Not for public use. 147 @internal 148 */ 149 CPPUHELPER_DLLPUBLIC ::osl::Mutex & SAL_CALL getImplHelperInitMutex(void) SAL_THROW( () ); 150 } 151 152 // 153 // settle down beavis, here comes the macro template hell :] 154 // 155 156 //================================================================================================== 157 158 /** Implementation helper macros 159 Not for common use. There are expanded forms of the macro usage in implbaseN.hxx/compbaseN.hxx. 160 So there is commonly no need to use these macros. Though, you may need to implement more than 161 12 interfaces. Then you have to declare something like the following in your headers 162 (where N is your demanded number of interfaces): 163 164 #define __IFC3 Ifc1, Ifc2, Ifc3, ... up to N 165 #define __CLASS_IFC3 class Ifc1, class Ifc2, class Ifc3, ... up to N 166 #define __PUBLIC_IFC3 public Ifc1, public Ifc2, public Ifc3, ... up to N 167 __DEF_IMPLHELPER_PRE( N ) 168 __IFC_WRITEOFFSET( 1 ) __IFC_WRITEOFFSET( 2 ) __IFC_WRITEOFFSET( 3 ), ... up to N 169 __DEF_IMPLHELPER_POST( N ) 170 171 @internal 172 */ 173 #define __DEF_IMPLHELPER_PRE( N ) \ 174 namespace cppu \ 175 { \ 176 struct ClassData##N : public ClassDataBase \ 177 { \ 178 Type_Offset arType2Offset[ N ]; \ 179 ClassData##N( sal_Int32 nClassCode ) SAL_THROW( () ) \ 180 : ClassDataBase( nClassCode ) \ 181 {} \ 182 }; \ 183 template< __CLASS_IFC##N > \ 184 class SAL_NO_VTABLE ImplHelperBase##N \ 185 : public ::com::sun::star::lang::XTypeProvider \ 186 , __PUBLIC_IFC##N \ 187 { \ 188 protected: \ 189 ClassData & SAL_CALL getClassData( ClassDataBase & s_aCD ) SAL_THROW( () ) \ 190 { \ 191 ClassData & rCD = * static_cast< ClassData * >( &s_aCD ); \ 192 if (! rCD.bOffsetsInit) \ 193 { \ 194 ::osl::MutexGuard aGuard( getImplHelperInitMutex() ); \ 195 if (! rCD.bOffsetsInit) \ 196 { \ 197 char * pBase = (char *)this; 198 /** Implementation helper macro: have a look at __DEF_IMPLHELPER_PRE 199 @internal 200 */ 201 #define __IFC_WRITEOFFSET( N ) \ 202 rCD.writeTypeOffset( ::getCppuType( (const ::com::sun::star::uno::Reference< Ifc##N > *)0 ), \ 203 (char *)(Ifc##N *)this - pBase ); 204 /** Implementation helper macro: have a look at __DEF_IMPLHELPER_PRE 205 @internal 206 */ 207 #define __DEF_IMPLHELPER_POST_A( N ) \ 208 rCD.bOffsetsInit = sal_True; \ 209 } \ 210 } \ 211 return rCD; \ 212 } \ 213 }; \ 214 template< __CLASS_IFC##N > \ 215 class SAL_NO_VTABLE ImplHelper##N \ 216 : public ImplHelperBase##N< __IFC##N > \ 217 { \ 218 static ClassData##N s_aCD; \ 219 public: \ 220 virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw (::com::sun::star::uno::RuntimeException) \ 221 { return this->getClassData( s_aCD ).query( rType, (ImplHelperBase##N< __IFC##N > *)this ); } \ 222 virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException) \ 223 { return this->getClassData( s_aCD ).getTypes(); } \ 224 virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (::com::sun::star::uno::RuntimeException) \ 225 { return this->getClassData( s_aCD ).getImplementationId(); } \ 226 }; \ 227 template< __CLASS_IFC##N > \ 228 class SAL_NO_VTABLE WeakImplHelper##N \ 229 : public ::cppu::OWeakObject \ 230 , public ImplHelperBase##N< __IFC##N > \ 231 { \ 232 static ClassData##N s_aCD; \ 233 public: \ 234 virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw (::com::sun::star::uno::RuntimeException) \ 235 { \ 236 ::com::sun::star::uno::Any aRet( this->getClassData( s_aCD ).query( rType, (ImplHelperBase##N< __IFC##N > *)this ) ); \ 237 return (aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType )); \ 238 } \ 239 virtual void SAL_CALL acquire() throw () \ 240 { OWeakObject::acquire(); } \ 241 virtual void SAL_CALL release() throw () \ 242 { OWeakObject::release(); } \ 243 virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException) \ 244 { return this->getClassData( s_aCD ).getTypes(); } \ 245 virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (::com::sun::star::uno::RuntimeException) \ 246 { return this->getClassData( s_aCD ).getImplementationId(); } \ 247 }; \ 248 template< __CLASS_IFC##N > \ 249 class SAL_NO_VTABLE WeakAggImplHelper##N \ 250 : public ::cppu::OWeakAggObject \ 251 , public ImplHelperBase##N< __IFC##N > \ 252 { \ 253 static ClassData##N s_aCD; \ 254 public: \ 255 virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw (::com::sun::star::uno::RuntimeException) \ 256 { return OWeakAggObject::queryInterface( rType ); } \ 257 virtual ::com::sun::star::uno::Any SAL_CALL queryAggregation( const ::com::sun::star::uno::Type & rType ) throw (::com::sun::star::uno::RuntimeException) \ 258 { \ 259 ::com::sun::star::uno::Any aRet( this->getClassData( s_aCD ).query( rType, (ImplHelperBase##N< __IFC##N > *)this ) ); \ 260 return (aRet.hasValue() ? aRet : OWeakAggObject::queryAggregation( rType )); \ 261 } \ 262 virtual void SAL_CALL acquire() throw () \ 263 { OWeakAggObject::acquire(); } \ 264 virtual void SAL_CALL release() throw () \ 265 { OWeakAggObject::release(); } \ 266 virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException) \ 267 { return this->getClassData( s_aCD ).getTypes(); } \ 268 virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (::com::sun::star::uno::RuntimeException) \ 269 { return this->getClassData( s_aCD ).getImplementationId(); } \ 270 }; 271 272 /** Implementation helper macro: have a look at __DEF_IMPLHELPER_PRE 273 @internal 274 */ 275 #define __DEF_IMPLHELPER_POST_B( N ) \ 276 template< __CLASS_IFC##N > \ 277 ClassData##N ImplHelper##N< __IFC##N >::s_aCD = ClassData##N( 0 ); \ 278 template< __CLASS_IFC##N > \ 279 ClassData##N WeakImplHelper##N< __IFC##N >::s_aCD = ClassData##N( 1 ); \ 280 template< __CLASS_IFC##N > \ 281 ClassData##N WeakAggImplHelper##N< __IFC##N >::s_aCD = ClassData##N( 2 ); 282 /** Implementation helper macro: have a look at __DEF_IMPLHELPER_PRE 283 @internal 284 */ 285 #define __DEF_IMPLHELPER_POST_C( N ) \ 286 } 287 //================================================================================================== 288 /** Implementation helper macro: have a look at __DEF_IMPLHELPER_PRE 289 @internal 290 */ 291 #define __DEF_IMPLHELPER_POST( N ) \ 292 __DEF_IMPLHELPER_POST_A( N ) \ 293 __DEF_IMPLHELPER_POST_B( N ) \ 294 __DEF_IMPLHELPER_POST_C( N ) 295 #endif 296 297