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