Update ooo320-m1
[ooovba.git] / cppuhelper / source / implbase.cxx
blob7f38f626679130ea4668d8b82f0248459a35f0d2
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: implbase.cxx,v $
10 * $Revision: 1.19 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_cppuhelper.hxx"
33 #include <cppuhelper/implbase.hxx>
34 #include <cppuhelper/compbase.hxx>
35 #include <osl/diagnose.h>
36 #include <rtl/uuid.h>
38 #include <com/sun/star/lang/XComponent.hpp>
39 #include "com/sun/star/uno/RuntimeException.hpp"
41 using namespace ::osl;
42 using namespace ::rtl;
43 using namespace ::com::sun::star;
44 using namespace ::com::sun::star::uno;
46 namespace cppu
48 //==================================================================================================
49 Mutex & SAL_CALL getImplHelperInitMutex(void) SAL_THROW( () )
51 static Mutex * s_pMutex = 0;
52 if (! s_pMutex)
54 MutexGuard aGuard( Mutex::getGlobalMutex() );
55 if (! s_pMutex)
57 static Mutex s_aMutex;
58 s_pMutex = & s_aMutex;
61 return * s_pMutex;
64 // ClassDataBase
65 //__________________________________________________________________________________________________
66 ClassDataBase::ClassDataBase() SAL_THROW( () )
67 : bOffsetsInit( sal_False )
68 , nType2Offset( 0 )
69 , nClassCode( 0 )
70 , pTypes( 0 )
71 , pId( 0 )
74 //__________________________________________________________________________________________________
75 ClassDataBase::ClassDataBase( sal_Int32 nClassCode_ ) SAL_THROW( () )
76 : bOffsetsInit( sal_False )
77 , nType2Offset( 0 )
78 , nClassCode( nClassCode_ )
79 , pTypes( 0 )
80 , pId( 0 )
83 //__________________________________________________________________________________________________
84 ClassDataBase::~ClassDataBase() SAL_THROW( () )
86 delete pTypes;
87 delete pId;
89 for ( sal_Int32 nPos = nType2Offset; nPos--; )
91 typelib_typedescription_release(
92 (typelib_TypeDescription *)((ClassData *)this)->arType2Offset[nPos].pTD );
96 // ClassData
97 //__________________________________________________________________________________________________
98 void ClassData::writeTypeOffset( const Type & rType, sal_Int32 nOffset ) SAL_THROW( () )
100 arType2Offset[nType2Offset].nOffset = nOffset;
102 arType2Offset[nType2Offset].pTD = 0;
103 typelib_typedescriptionreference_getDescription(
104 (typelib_TypeDescription **)&arType2Offset[nType2Offset].pTD, rType.getTypeLibType() );
106 if (arType2Offset[nType2Offset].pTD)
107 ++nType2Offset;
108 #if OSL_DEBUG_LEVEL > 1
109 else
111 OString msg( "### cannot get type description for " );
112 msg += OUStringToOString( rType.getTypeName(), RTL_TEXTENCODING_ASCII_US );
113 OSL_ENSURE( sal_False, msg.getStr() );
115 #endif
117 //__________________________________________________________________________________________________
118 void ClassData::initTypeProvider() SAL_THROW( () )
120 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
121 if (! pTypes)
123 // create id
124 pId = new Sequence< sal_Int8 >( 16 );
125 rtl_createUuid( (sal_uInt8 *)pId->getArray(), 0, sal_True );
127 // collect types
128 Sequence< Type > * types = new Sequence< Type >(
129 nType2Offset + 1 + (nClassCode == 4 ? 2 : nClassCode) );
130 Type * pTypeAr = types->getArray();
132 // given types
133 sal_Int32 nPos = nType2Offset;
134 while (nPos--)
135 pTypeAr[nPos] = ((typelib_TypeDescription *)arType2Offset[nPos].pTD)->pWeakRef;
137 // XTypeProvider
138 pTypeAr[nType2Offset] = ::getCppuType( (const Reference< lang::XTypeProvider > *)0 );
140 // class code extra types: [[XComponent,] XWeak[, XAggregation]]
141 switch (nClassCode)
143 case 4:
144 pTypeAr[nType2Offset +2] = ::getCppuType( (const Reference< lang::XComponent > *)0 );
145 pTypeAr[nType2Offset +1] = ::getCppuType( (const Reference< XWeak > *)0 );
146 break;
147 case 3:
148 pTypeAr[nType2Offset +3] = ::getCppuType( (const Reference< lang::XComponent > *)0 );
149 case 2:
150 pTypeAr[nType2Offset +2] = ::getCppuType( (const Reference< XAggregation > *)0 );
151 case 1:
152 pTypeAr[nType2Offset +1] = ::getCppuType( (const Reference< XWeak > *)0 );
155 pTypes = types;
158 //__________________________________________________________________________________________________
159 Sequence< Type > ClassData::getTypes() SAL_THROW( () )
161 if (! pTypes)
162 initTypeProvider();
163 return *pTypes;
165 //__________________________________________________________________________________________________
166 Sequence< sal_Int8 > ClassData::getImplementationId() SAL_THROW( () )
168 if (! pTypes)
169 initTypeProvider();
170 return *pId;
173 //--------------------------------------------------------------------------------------------------
174 static inline sal_Bool td_equals(
175 typelib_TypeDescription * pTD, typelib_TypeDescriptionReference * pType )
176 SAL_THROW( () )
178 return (pTD->pWeakRef == pType ||
179 (pTD->pTypeName->length == pType->pTypeName->length &&
180 rtl_ustr_compare( pTD->pTypeName->buffer, pType->pTypeName->buffer ) == 0));
182 //__________________________________________________________________________________________________
183 Any ClassData::query( const Type & rType, lang::XTypeProvider * pBase ) SAL_THROW( () )
185 if (rType == ::getCppuType( (const Reference< XInterface > *)0 ))
186 return Any( &pBase, ::getCppuType( (const Reference< XInterface > *)0 ) );
187 for ( sal_Int32 nPos = 0; nPos < nType2Offset; ++nPos )
189 const Type_Offset & rTO = arType2Offset[nPos];
190 typelib_InterfaceTypeDescription * pTD = rTO.pTD;
191 while (pTD)
193 if (td_equals( (typelib_TypeDescription *)pTD,
194 *(typelib_TypeDescriptionReference **)&rType ))
196 void * pInterface = (char *)pBase + rTO.nOffset;
197 return Any( &pInterface, (typelib_TypeDescription *)pTD );
199 pTD = pTD->pBaseTypeDescription;
202 if (rType == ::getCppuType( (const Reference< lang::XTypeProvider > *)0 ))
203 return Any( &pBase, ::getCppuType( (const Reference< lang::XTypeProvider > *)0 ) );
205 return Any();
208 //##################################################################################################
209 //##################################################################################################
210 //##################################################################################################
212 // WeakComponentImplHelperBase
213 //__________________________________________________________________________________________________
214 WeakComponentImplHelperBase::WeakComponentImplHelperBase( Mutex & rMutex )
215 SAL_THROW( () )
216 : rBHelper( rMutex )
219 //__________________________________________________________________________________________________
220 WeakComponentImplHelperBase::~WeakComponentImplHelperBase()
221 SAL_THROW( () )
224 //__________________________________________________________________________________________________
225 void WeakComponentImplHelperBase::disposing()
228 //__________________________________________________________________________________________________
229 Any WeakComponentImplHelperBase::queryInterface( Type const & rType )
230 throw (RuntimeException)
232 if (rType == ::getCppuType( (Reference< lang::XComponent > const *)0 ))
234 void * p = static_cast< lang::XComponent * >( this );
235 return Any( &p, rType );
237 return OWeakObject::queryInterface( rType );
239 //__________________________________________________________________________________________________
240 void WeakComponentImplHelperBase::acquire()
241 throw ()
243 OWeakObject::acquire();
245 //__________________________________________________________________________________________________
246 void WeakComponentImplHelperBase::release()
247 throw ()
249 if (osl_decrementInterlockedCount( &m_refCount ) == 0) {
250 // restore reference count:
251 osl_incrementInterlockedCount( &m_refCount );
252 if (! rBHelper.bDisposed) {
253 try {
254 dispose();
256 catch (RuntimeException const& exc) { // don't break throw ()
257 OSL_ENSURE(
258 false, OUStringToOString(
259 exc.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
260 static_cast<void>(exc);
262 OSL_ASSERT( rBHelper.bDisposed );
264 OWeakObject::release();
267 //__________________________________________________________________________________________________
268 void WeakComponentImplHelperBase::dispose()
269 throw (RuntimeException)
271 ClearableMutexGuard aGuard( rBHelper.rMutex );
272 if (!rBHelper.bDisposed && !rBHelper.bInDispose)
274 rBHelper.bInDispose = sal_True;
275 aGuard.clear();
278 // side effect: keeping a reference to this
279 lang::EventObject aEvt( static_cast< OWeakObject * >( this ) );
282 rBHelper.aLC.disposeAndClear( aEvt );
283 disposing();
285 catch (...)
287 MutexGuard aGuard2( rBHelper.rMutex );
288 // bDisposed and bInDispose must be set in this order:
289 rBHelper.bDisposed = sal_True;
290 rBHelper.bInDispose = sal_False;
291 throw;
293 MutexGuard aGuard2( rBHelper.rMutex );
294 // bDisposed and bInDispose must be set in this order:
295 rBHelper.bDisposed = sal_True;
296 rBHelper.bInDispose = sal_False;
298 catch (RuntimeException &)
300 throw;
302 catch (Exception & exc)
304 throw RuntimeException(
305 OUString( RTL_CONSTASCII_USTRINGPARAM(
306 "unexpected UNO exception caught: ") ) +
307 exc.Message, Reference< XInterface >() );
311 //__________________________________________________________________________________________________
312 void WeakComponentImplHelperBase::addEventListener(
313 Reference< lang::XEventListener > const & xListener )
314 throw (RuntimeException)
316 ClearableMutexGuard aGuard( rBHelper.rMutex );
317 if (rBHelper.bDisposed || rBHelper.bInDispose)
319 aGuard.clear();
320 lang::EventObject aEvt( static_cast< OWeakObject * >( this ) );
321 xListener->disposing( aEvt );
323 else
325 rBHelper.addListener( ::getCppuType( &xListener ), xListener );
328 //__________________________________________________________________________________________________
329 void WeakComponentImplHelperBase::removeEventListener(
330 Reference< lang::XEventListener > const & xListener )
331 throw (RuntimeException)
333 rBHelper.removeListener( ::getCppuType( &xListener ), xListener );
336 // WeakAggComponentImplHelperBase
337 //__________________________________________________________________________________________________
338 WeakAggComponentImplHelperBase::WeakAggComponentImplHelperBase( Mutex & rMutex )
339 SAL_THROW( () )
340 : rBHelper( rMutex )
343 //__________________________________________________________________________________________________
344 WeakAggComponentImplHelperBase::~WeakAggComponentImplHelperBase()
345 SAL_THROW( () )
348 //__________________________________________________________________________________________________
349 void WeakAggComponentImplHelperBase::disposing()
352 //__________________________________________________________________________________________________
353 Any WeakAggComponentImplHelperBase::queryInterface( Type const & rType )
354 throw (RuntimeException)
356 return OWeakAggObject::queryInterface( rType );
358 //__________________________________________________________________________________________________
359 Any WeakAggComponentImplHelperBase::queryAggregation( Type const & rType )
360 throw (RuntimeException)
362 if (rType == ::getCppuType( (Reference< lang::XComponent > const *)0 ))
364 void * p = static_cast< lang::XComponent * >( this );
365 return Any( &p, rType );
367 return OWeakAggObject::queryAggregation( rType );
369 //__________________________________________________________________________________________________
370 void WeakAggComponentImplHelperBase::acquire()
371 throw ()
373 OWeakAggObject::acquire();
375 //__________________________________________________________________________________________________
376 void WeakAggComponentImplHelperBase::release()
377 throw ()
379 Reference<XInterface> const xDelegator_(xDelegator);
380 if (xDelegator_.is()) {
381 OWeakAggObject::release();
383 else if (osl_decrementInterlockedCount( &m_refCount ) == 0) {
384 // restore reference count:
385 osl_incrementInterlockedCount( &m_refCount );
386 if (! rBHelper.bDisposed) {
387 try {
388 dispose();
390 catch (RuntimeException const& exc) { // don't break throw ()
391 OSL_ENSURE(
392 false, OUStringToOString(
393 exc.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
394 static_cast<void>(exc);
396 OSL_ASSERT( rBHelper.bDisposed );
398 OWeakAggObject::release();
401 //__________________________________________________________________________________________________
402 void WeakAggComponentImplHelperBase::dispose()
403 throw (RuntimeException)
405 ClearableMutexGuard aGuard( rBHelper.rMutex );
406 if (!rBHelper.bDisposed && !rBHelper.bInDispose)
408 rBHelper.bInDispose = sal_True;
409 aGuard.clear();
412 // side effect: keeping a reference to this
413 lang::EventObject aEvt( static_cast< OWeakObject * >( this ) );
416 rBHelper.aLC.disposeAndClear( aEvt );
417 disposing();
419 catch (...)
421 MutexGuard aGuard2( rBHelper.rMutex );
422 // bDisposed and bInDispose must be set in this order:
423 rBHelper.bDisposed = sal_True;
424 rBHelper.bInDispose = sal_False;
425 throw;
427 MutexGuard aGuard2( rBHelper.rMutex );
428 // bDisposed and bInDispose must be set in this order:
429 rBHelper.bDisposed = sal_True;
430 rBHelper.bInDispose = sal_False;
432 catch (RuntimeException &)
434 throw;
436 catch (Exception & exc)
438 throw RuntimeException(
439 OUString( RTL_CONSTASCII_USTRINGPARAM(
440 "unexpected UNO exception caught: ") ) +
441 exc.Message, Reference< XInterface >() );
445 //__________________________________________________________________________________________________
446 void WeakAggComponentImplHelperBase::addEventListener(
447 Reference< lang::XEventListener > const & xListener )
448 throw (RuntimeException)
450 ClearableMutexGuard aGuard( rBHelper.rMutex );
451 if (rBHelper.bDisposed || rBHelper.bInDispose)
453 aGuard.clear();
454 lang::EventObject aEvt( static_cast< OWeakObject * >( this ) );
455 xListener->disposing( aEvt );
457 else
459 rBHelper.addListener( ::getCppuType( &xListener ), xListener );
462 //__________________________________________________________________________________________________
463 void WeakAggComponentImplHelperBase::removeEventListener(
464 Reference< lang::XEventListener > const & xListener )
465 throw (RuntimeException)
467 rBHelper.removeListener( ::getCppuType( &xListener ), xListener );