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>
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
;
46 //==================================================================================================
47 Mutex
& SAL_CALL
getImplHelperInitMutex(void) SAL_THROW( () )
49 static Mutex
* s_pMutex
= 0;
52 MutexGuard
aGuard( Mutex::getGlobalMutex() );
55 static Mutex s_aMutex
;
56 s_pMutex
= & s_aMutex
;
63 //__________________________________________________________________________________________________
64 ClassDataBase::ClassDataBase() SAL_THROW( () )
65 : bOffsetsInit( sal_False
)
72 //__________________________________________________________________________________________________
73 ClassDataBase::ClassDataBase( sal_Int32 nClassCode_
) SAL_THROW( () )
74 : bOffsetsInit( sal_False
)
76 , nClassCode( nClassCode_
)
81 //__________________________________________________________________________________________________
82 ClassDataBase::~ClassDataBase() SAL_THROW( () )
87 for ( sal_Int32 nPos
= nType2Offset
; nPos
--; )
89 typelib_typedescription_release(
90 (typelib_TypeDescription
*)((ClassData
*)this)->arType2Offset
[nPos
].pTD
);
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
)
106 #if OSL_DEBUG_LEVEL > 1
109 OString
msg( "### cannot get type description for " );
110 msg
+= OUStringToOString( rType
.getTypeName(), RTL_TEXTENCODING_ASCII_US
);
111 OSL_ENSURE( sal_False
, msg
.getStr() );
115 //__________________________________________________________________________________________________
116 void ClassData::initTypeProvider() SAL_THROW( () )
118 ::osl::MutexGuard
aGuard( ::osl::Mutex::getGlobalMutex() );
122 pId
= new Sequence
< sal_Int8
>( 16 );
123 rtl_createUuid( (sal_uInt8
*)pId
->getArray(), 0, sal_True
);
126 Sequence
< Type
> * types
= new Sequence
< Type
>(
127 nType2Offset
+ 1 + (nClassCode
== 4 ? 2 : nClassCode
) );
128 Type
* pTypeAr
= types
->getArray();
131 sal_Int32 nPos
= nType2Offset
;
133 pTypeAr
[nPos
] = ((typelib_TypeDescription
*)arType2Offset
[nPos
].pTD
)->pWeakRef
;
136 pTypeAr
[nType2Offset
] = ::getCppuType( (const Reference
< lang::XTypeProvider
> *)0 );
138 // class code extra types: [[XComponent,] XWeak[, XAggregation]]
142 pTypeAr
[nType2Offset
+2] = ::getCppuType( (const Reference
< lang::XComponent
> *)0 );
143 pTypeAr
[nType2Offset
+1] = ::getCppuType( (const Reference
< XWeak
> *)0 );
146 pTypeAr
[nType2Offset
+3] = ::getCppuType( (const Reference
< lang::XComponent
> *)0 );
148 pTypeAr
[nType2Offset
+2] = ::getCppuType( (const Reference
< XAggregation
> *)0 );
150 pTypeAr
[nType2Offset
+1] = ::getCppuType( (const Reference
< XWeak
> *)0 );
156 //__________________________________________________________________________________________________
157 Sequence
< Type
> ClassData::getTypes() SAL_THROW( () )
163 //__________________________________________________________________________________________________
164 Sequence
< sal_Int8
> ClassData::getImplementationId() SAL_THROW( () )
171 //--------------------------------------------------------------------------------------------------
172 static inline sal_Bool
td_equals(
173 typelib_TypeDescription
* pTD
, typelib_TypeDescriptionReference
* pType
)
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
;
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 ) );
206 //##################################################################################################
207 //##################################################################################################
208 //##################################################################################################
210 // WeakComponentImplHelperBase
211 //__________________________________________________________________________________________________
212 WeakComponentImplHelperBase::WeakComponentImplHelperBase( Mutex
& rMutex
)
217 //__________________________________________________________________________________________________
218 WeakComponentImplHelperBase::~WeakComponentImplHelperBase()
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()
241 OWeakObject::acquire();
243 //__________________________________________________________________________________________________
244 void WeakComponentImplHelperBase::release()
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
) {
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 // 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
) {
392 catch (RuntimeException
const& exc
) { // don't break throw ()
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
;
414 // side effect: keeping a reference to this
415 lang::EventObject
aEvt( static_cast< OWeakObject
* >( this ) );
418 rBHelper
.aLC
.disposeAndClear( aEvt
);
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
;
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
&)
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
)
456 lang::EventObject
aEvt( static_cast< OWeakObject
* >( this ) );
457 xListener
->disposing( aEvt
);
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: */