merged tag LIBREOFFICE_3_2_99_3
[LibreOffice.git] / cppuhelper / source / implbase.cxx
blob60f153194bef7a71a6b28d66b4d6f29cfbf357b1
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 // MARKER(update_precomp.py): autogen include statement, do not remove
30 #include "precompiled_cppuhelper.hxx"
31 #include <cppuhelper/implbase.hxx>
32 #include <cppuhelper/compbase.hxx>
33 #include <osl/diagnose.h>
34 #include <rtl/uuid.h>
36 #include <com/sun/star/lang/XComponent.hpp>
37 #include "com/sun/star/uno/RuntimeException.hpp"
39 using namespace ::osl;
40 using namespace ::rtl;
41 using namespace ::com::sun::star;
42 using namespace ::com::sun::star::uno;
44 namespace cppu
46 //==================================================================================================
47 Mutex & SAL_CALL getImplHelperInitMutex(void) SAL_THROW( () )
49 static Mutex * s_pMutex = 0;
50 if (! s_pMutex)
52 MutexGuard aGuard( Mutex::getGlobalMutex() );
53 if (! s_pMutex)
55 static Mutex s_aMutex;
56 s_pMutex = & s_aMutex;
59 return * s_pMutex;
62 // ClassDataBase
63 //__________________________________________________________________________________________________
64 ClassDataBase::ClassDataBase() SAL_THROW( () )
65 : bOffsetsInit( sal_False )
66 , nType2Offset( 0 )
67 , nClassCode( 0 )
68 , pTypes( 0 )
69 , pId( 0 )
72 //__________________________________________________________________________________________________
73 ClassDataBase::ClassDataBase( sal_Int32 nClassCode_ ) SAL_THROW( () )
74 : bOffsetsInit( sal_False )
75 , nType2Offset( 0 )
76 , nClassCode( nClassCode_ )
77 , pTypes( 0 )
78 , pId( 0 )
81 //__________________________________________________________________________________________________
82 ClassDataBase::~ClassDataBase() SAL_THROW( () )
84 delete pTypes;
85 delete pId;
87 for ( sal_Int32 nPos = nType2Offset; nPos--; )
89 typelib_typedescription_release(
90 (typelib_TypeDescription *)((ClassData *)this)->arType2Offset[nPos].pTD );
94 // ClassData
95 //__________________________________________________________________________________________________
96 void ClassData::writeTypeOffset( const Type & rType, sal_Int32 nOffset ) SAL_THROW( () )
98 arType2Offset[nType2Offset].nOffset = nOffset;
100 arType2Offset[nType2Offset].pTD = 0;
101 typelib_typedescriptionreference_getDescription(
102 (typelib_TypeDescription **)&arType2Offset[nType2Offset].pTD, rType.getTypeLibType() );
104 if (arType2Offset[nType2Offset].pTD)
105 ++nType2Offset;
106 #if OSL_DEBUG_LEVEL > 1
107 else
109 OString msg( "### cannot get type description for " );
110 msg += OUStringToOString( rType.getTypeName(), RTL_TEXTENCODING_ASCII_US );
111 OSL_ENSURE( sal_False, msg.getStr() );
113 #endif
115 //__________________________________________________________________________________________________
116 void ClassData::initTypeProvider() SAL_THROW( () )
118 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
119 if (! pTypes)
121 // create id
122 pId = new Sequence< sal_Int8 >( 16 );
123 rtl_createUuid( (sal_uInt8 *)pId->getArray(), 0, sal_True );
125 // collect types
126 Sequence< Type > * types = new Sequence< Type >(
127 nType2Offset + 1 + (nClassCode == 4 ? 2 : nClassCode) );
128 Type * pTypeAr = types->getArray();
130 // given types
131 sal_Int32 nPos = nType2Offset;
132 while (nPos--)
133 pTypeAr[nPos] = ((typelib_TypeDescription *)arType2Offset[nPos].pTD)->pWeakRef;
135 // XTypeProvider
136 pTypeAr[nType2Offset] = ::getCppuType( (const Reference< lang::XTypeProvider > *)0 );
138 // class code extra types: [[XComponent,] XWeak[, XAggregation]]
139 switch (nClassCode)
141 case 4:
142 pTypeAr[nType2Offset +2] = ::getCppuType( (const Reference< lang::XComponent > *)0 );
143 pTypeAr[nType2Offset +1] = ::getCppuType( (const Reference< XWeak > *)0 );
144 break;
145 case 3:
146 pTypeAr[nType2Offset +3] = ::getCppuType( (const Reference< lang::XComponent > *)0 );
147 case 2:
148 pTypeAr[nType2Offset +2] = ::getCppuType( (const Reference< XAggregation > *)0 );
149 case 1:
150 pTypeAr[nType2Offset +1] = ::getCppuType( (const Reference< XWeak > *)0 );
153 pTypes = types;
156 //__________________________________________________________________________________________________
157 Sequence< Type > ClassData::getTypes() SAL_THROW( () )
159 if (! pTypes)
160 initTypeProvider();
161 return *pTypes;
163 //__________________________________________________________________________________________________
164 Sequence< sal_Int8 > ClassData::getImplementationId() SAL_THROW( () )
166 if (! pTypes)
167 initTypeProvider();
168 return *pId;
171 //--------------------------------------------------------------------------------------------------
172 static inline sal_Bool td_equals(
173 typelib_TypeDescription * pTD, typelib_TypeDescriptionReference * pType )
174 SAL_THROW( () )
176 return (pTD->pWeakRef == pType ||
177 (pTD->pTypeName->length == pType->pTypeName->length &&
178 rtl_ustr_compare( pTD->pTypeName->buffer, pType->pTypeName->buffer ) == 0));
180 //__________________________________________________________________________________________________
181 Any ClassData::query( const Type & rType, lang::XTypeProvider * pBase ) SAL_THROW( () )
183 if (rType == ::getCppuType( (const Reference< XInterface > *)0 ))
184 return Any( &pBase, ::getCppuType( (const Reference< XInterface > *)0 ) );
185 for ( sal_Int32 nPos = 0; nPos < nType2Offset; ++nPos )
187 const Type_Offset & rTO = arType2Offset[nPos];
188 typelib_InterfaceTypeDescription * pTD = rTO.pTD;
189 while (pTD)
191 if (td_equals( (typelib_TypeDescription *)pTD,
192 *(typelib_TypeDescriptionReference **)&rType ))
194 void * pInterface = (char *)pBase + rTO.nOffset;
195 return Any( &pInterface, (typelib_TypeDescription *)pTD );
197 pTD = pTD->pBaseTypeDescription;
200 if (rType == ::getCppuType( (const Reference< lang::XTypeProvider > *)0 ))
201 return Any( &pBase, ::getCppuType( (const Reference< lang::XTypeProvider > *)0 ) );
203 return Any();
206 //##################################################################################################
207 //##################################################################################################
208 //##################################################################################################
210 // WeakComponentImplHelperBase
211 //__________________________________________________________________________________________________
212 WeakComponentImplHelperBase::WeakComponentImplHelperBase( Mutex & rMutex )
213 SAL_THROW( () )
214 : rBHelper( rMutex )
217 //__________________________________________________________________________________________________
218 WeakComponentImplHelperBase::~WeakComponentImplHelperBase()
219 SAL_THROW( () )
222 //__________________________________________________________________________________________________
223 void WeakComponentImplHelperBase::disposing()
226 //__________________________________________________________________________________________________
227 Any WeakComponentImplHelperBase::queryInterface( Type const & rType )
228 throw (RuntimeException)
230 if (rType == ::getCppuType( (Reference< lang::XComponent > const *)0 ))
232 void * p = static_cast< lang::XComponent * >( this );
233 return Any( &p, rType );
235 return OWeakObject::queryInterface( rType );
237 //__________________________________________________________________________________________________
238 void WeakComponentImplHelperBase::acquire()
239 throw ()
241 OWeakObject::acquire();
243 //__________________________________________________________________________________________________
244 void WeakComponentImplHelperBase::release()
245 throw ()
247 if (osl_decrementInterlockedCount( &m_refCount ) == 0) {
248 // ensure no other references are created, via the weak connection point, from now on
249 disposeWeakConnectionPoint();
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 // ensure no other references are created, via the weak connection point, from now on
385 disposeWeakConnectionPoint();
386 // restore reference count:
387 osl_incrementInterlockedCount( &m_refCount );
388 if (! rBHelper.bDisposed) {
389 try {
390 dispose();
392 catch (RuntimeException const& exc) { // don't break throw ()
393 OSL_ENSURE(
394 false, OUStringToOString(
395 exc.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
396 static_cast<void>(exc);
398 OSL_ASSERT( rBHelper.bDisposed );
400 OWeakAggObject::release();
403 //__________________________________________________________________________________________________
404 void WeakAggComponentImplHelperBase::dispose()
405 throw (RuntimeException)
407 ClearableMutexGuard aGuard( rBHelper.rMutex );
408 if (!rBHelper.bDisposed && !rBHelper.bInDispose)
410 rBHelper.bInDispose = sal_True;
411 aGuard.clear();
414 // side effect: keeping a reference to this
415 lang::EventObject aEvt( static_cast< OWeakObject * >( this ) );
418 rBHelper.aLC.disposeAndClear( aEvt );
419 disposing();
421 catch (...)
423 MutexGuard aGuard2( rBHelper.rMutex );
424 // bDisposed and bInDispose must be set in this order:
425 rBHelper.bDisposed = sal_True;
426 rBHelper.bInDispose = sal_False;
427 throw;
429 MutexGuard aGuard2( rBHelper.rMutex );
430 // bDisposed and bInDispose must be set in this order:
431 rBHelper.bDisposed = sal_True;
432 rBHelper.bInDispose = sal_False;
434 catch (RuntimeException &)
436 throw;
438 catch (Exception & exc)
440 throw RuntimeException(
441 OUString( RTL_CONSTASCII_USTRINGPARAM(
442 "unexpected UNO exception caught: ") ) +
443 exc.Message, Reference< XInterface >() );
447 //__________________________________________________________________________________________________
448 void WeakAggComponentImplHelperBase::addEventListener(
449 Reference< lang::XEventListener > const & xListener )
450 throw (RuntimeException)
452 ClearableMutexGuard aGuard( rBHelper.rMutex );
453 if (rBHelper.bDisposed || rBHelper.bInDispose)
455 aGuard.clear();
456 lang::EventObject aEvt( static_cast< OWeakObject * >( this ) );
457 xListener->disposing( aEvt );
459 else
461 rBHelper.addListener( ::getCppuType( &xListener ), xListener );
464 //__________________________________________________________________________________________________
465 void WeakAggComponentImplHelperBase::removeEventListener(
466 Reference< lang::XEventListener > const & xListener )
467 throw (RuntimeException)
469 rBHelper.removeListener( ::getCppuType( &xListener ), xListener );
474 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */