1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: implbase.cxx,v $
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>
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
;
48 //==================================================================================================
49 Mutex
& SAL_CALL
getImplHelperInitMutex(void) SAL_THROW( () )
51 static Mutex
* s_pMutex
= 0;
54 MutexGuard
aGuard( Mutex::getGlobalMutex() );
57 static Mutex s_aMutex
;
58 s_pMutex
= & s_aMutex
;
65 //__________________________________________________________________________________________________
66 ClassDataBase::ClassDataBase() SAL_THROW( () )
67 : bOffsetsInit( sal_False
)
74 //__________________________________________________________________________________________________
75 ClassDataBase::ClassDataBase( sal_Int32 nClassCode_
) SAL_THROW( () )
76 : bOffsetsInit( sal_False
)
78 , nClassCode( nClassCode_
)
83 //__________________________________________________________________________________________________
84 ClassDataBase::~ClassDataBase() SAL_THROW( () )
89 for ( sal_Int32 nPos
= nType2Offset
; nPos
--; )
91 typelib_typedescription_release(
92 (typelib_TypeDescription
*)((ClassData
*)this)->arType2Offset
[nPos
].pTD
);
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
)
108 #if OSL_DEBUG_LEVEL > 1
111 OString
msg( "### cannot get type description for " );
112 msg
+= OUStringToOString( rType
.getTypeName(), RTL_TEXTENCODING_ASCII_US
);
113 OSL_ENSURE( sal_False
, msg
.getStr() );
117 //__________________________________________________________________________________________________
118 void ClassData::initTypeProvider() SAL_THROW( () )
120 ::osl::MutexGuard
aGuard( ::osl::Mutex::getGlobalMutex() );
124 pId
= new Sequence
< sal_Int8
>( 16 );
125 rtl_createUuid( (sal_uInt8
*)pId
->getArray(), 0, sal_True
);
128 Sequence
< Type
> * types
= new Sequence
< Type
>(
129 nType2Offset
+ 1 + (nClassCode
== 4 ? 2 : nClassCode
) );
130 Type
* pTypeAr
= types
->getArray();
133 sal_Int32 nPos
= nType2Offset
;
135 pTypeAr
[nPos
] = ((typelib_TypeDescription
*)arType2Offset
[nPos
].pTD
)->pWeakRef
;
138 pTypeAr
[nType2Offset
] = ::getCppuType( (const Reference
< lang::XTypeProvider
> *)0 );
140 // class code extra types: [[XComponent,] XWeak[, XAggregation]]
144 pTypeAr
[nType2Offset
+2] = ::getCppuType( (const Reference
< lang::XComponent
> *)0 );
145 pTypeAr
[nType2Offset
+1] = ::getCppuType( (const Reference
< XWeak
> *)0 );
148 pTypeAr
[nType2Offset
+3] = ::getCppuType( (const Reference
< lang::XComponent
> *)0 );
150 pTypeAr
[nType2Offset
+2] = ::getCppuType( (const Reference
< XAggregation
> *)0 );
152 pTypeAr
[nType2Offset
+1] = ::getCppuType( (const Reference
< XWeak
> *)0 );
158 //__________________________________________________________________________________________________
159 Sequence
< Type
> ClassData::getTypes() SAL_THROW( () )
165 //__________________________________________________________________________________________________
166 Sequence
< sal_Int8
> ClassData::getImplementationId() SAL_THROW( () )
173 //--------------------------------------------------------------------------------------------------
174 static inline sal_Bool
td_equals(
175 typelib_TypeDescription
* pTD
, typelib_TypeDescriptionReference
* pType
)
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
;
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 ) );
208 //##################################################################################################
209 //##################################################################################################
210 //##################################################################################################
212 // WeakComponentImplHelperBase
213 //__________________________________________________________________________________________________
214 WeakComponentImplHelperBase::WeakComponentImplHelperBase( Mutex
& rMutex
)
219 //__________________________________________________________________________________________________
220 WeakComponentImplHelperBase::~WeakComponentImplHelperBase()
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()
243 OWeakObject::acquire();
245 //__________________________________________________________________________________________________
246 void WeakComponentImplHelperBase::release()
249 if (osl_decrementInterlockedCount( &m_refCount
) == 0) {
250 // restore reference count:
251 osl_incrementInterlockedCount( &m_refCount
);
252 if (! rBHelper
.bDisposed
) {
256 catch (RuntimeException
const& exc
) { // don't break throw ()
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
;
278 // side effect: keeping a reference to this
279 lang::EventObject
aEvt( static_cast< OWeakObject
* >( this ) );
282 rBHelper
.aLC
.disposeAndClear( aEvt
);
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
;
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
&)
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
)
320 lang::EventObject
aEvt( static_cast< OWeakObject
* >( this ) );
321 xListener
->disposing( aEvt
);
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
)
343 //__________________________________________________________________________________________________
344 WeakAggComponentImplHelperBase::~WeakAggComponentImplHelperBase()
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()
373 OWeakAggObject::acquire();
375 //__________________________________________________________________________________________________
376 void WeakAggComponentImplHelperBase::release()
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
) {
390 catch (RuntimeException
const& exc
) { // don't break throw ()
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
;
412 // side effect: keeping a reference to this
413 lang::EventObject
aEvt( static_cast< OWeakObject
* >( this ) );
416 rBHelper
.aLC
.disposeAndClear( aEvt
);
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
;
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
&)
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
)
454 lang::EventObject
aEvt( static_cast< OWeakObject
* >( this ) );
455 xListener
->disposing( aEvt
);
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
);