1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <cppuhelper/implbase.hxx>
21 #include <cppuhelper/compbase.hxx>
22 #include <osl/diagnose.h>
23 #include <rtl/instance.hxx>
26 #include <com/sun/star/lang/XComponent.hpp>
27 #include "com/sun/star/uno/RuntimeException.hpp"
29 using namespace ::osl
;
30 using namespace ::rtl
;
31 using namespace ::com::sun::star
;
32 using namespace ::com::sun::star::uno
;
36 class theImplHelperInitMutex
: public rtl::Static
<Mutex
, theImplHelperInitMutex
>{};
41 //==================================================================================================
42 Mutex
& SAL_CALL
getImplHelperInitMutex(void) SAL_THROW(())
44 return theImplHelperInitMutex::get();
48 //__________________________________________________________________________________________________
49 ClassDataBase::ClassDataBase() SAL_THROW(())
50 : bOffsetsInit( sal_False
)
57 //__________________________________________________________________________________________________
58 ClassDataBase::ClassDataBase( sal_Int32 nClassCode_
) SAL_THROW(())
59 : bOffsetsInit( sal_False
)
61 , nClassCode( nClassCode_
)
66 //__________________________________________________________________________________________________
67 ClassDataBase::~ClassDataBase() SAL_THROW(())
72 for ( sal_Int32 nPos
= nType2Offset
; nPos
--; )
74 typelib_typedescription_release(
75 (typelib_TypeDescription
*)((ClassData
*)this)->arType2Offset
[nPos
].pTD
);
80 //__________________________________________________________________________________________________
81 void ClassData::writeTypeOffset( const Type
& rType
, sal_Int32 nOffset
) SAL_THROW(())
83 arType2Offset
[nType2Offset
].nOffset
= nOffset
;
85 arType2Offset
[nType2Offset
].pTD
= 0;
86 typelib_typedescriptionreference_getDescription(
87 (typelib_TypeDescription
**)&arType2Offset
[nType2Offset
].pTD
, rType
.getTypeLibType() );
89 if (arType2Offset
[nType2Offset
].pTD
)
91 #if OSL_DEBUG_LEVEL > 1
94 OString
msg( "### cannot get type description for " );
95 msg
+= OUStringToOString( rType
.getTypeName(), RTL_TEXTENCODING_ASCII_US
);
96 OSL_FAIL( msg
.getStr() );
100 //__________________________________________________________________________________________________
101 void ClassData::initTypeProvider() SAL_THROW(())
103 ::osl::MutexGuard
aGuard( ::osl::Mutex::getGlobalMutex() );
107 pId
= new Sequence
< sal_Int8
>( 16 );
108 rtl_createUuid( (sal_uInt8
*)pId
->getArray(), 0, sal_True
);
111 Sequence
< Type
> * types
= new Sequence
< Type
>(
112 nType2Offset
+ 1 + (nClassCode
== 4 ? 2 : nClassCode
) );
113 Type
* pTypeAr
= types
->getArray();
116 sal_Int32 nPos
= nType2Offset
;
118 pTypeAr
[nPos
] = ((typelib_TypeDescription
*)arType2Offset
[nPos
].pTD
)->pWeakRef
;
121 pTypeAr
[nType2Offset
] = ::getCppuType( (const Reference
< lang::XTypeProvider
> *)0 );
123 // class code extra types: [[XComponent,] XWeak[, XAggregation]]
127 pTypeAr
[nType2Offset
+2] = ::getCppuType( (const Reference
< lang::XComponent
> *)0 );
128 pTypeAr
[nType2Offset
+1] = ::getCppuType( (const Reference
< XWeak
> *)0 );
131 pTypeAr
[nType2Offset
+3] = ::getCppuType( (const Reference
< lang::XComponent
> *)0 );
133 pTypeAr
[nType2Offset
+2] = ::getCppuType( (const Reference
< XAggregation
> *)0 );
135 pTypeAr
[nType2Offset
+1] = ::getCppuType( (const Reference
< XWeak
> *)0 );
141 //__________________________________________________________________________________________________
142 Sequence
< Type
> ClassData::getTypes() SAL_THROW(())
148 //__________________________________________________________________________________________________
149 Sequence
< sal_Int8
> ClassData::getImplementationId() SAL_THROW(())
156 //--------------------------------------------------------------------------------------------------
157 static inline sal_Bool
td_equals(
158 typelib_TypeDescription
* pTD
, typelib_TypeDescriptionReference
* pType
)
161 return (pTD
->pWeakRef
== pType
||
162 (pTD
->pTypeName
->length
== pType
->pTypeName
->length
&&
163 rtl_ustr_compare( pTD
->pTypeName
->buffer
, pType
->pTypeName
->buffer
) == 0));
165 //__________________________________________________________________________________________________
166 Any
ClassData::query( const Type
& rType
, lang::XTypeProvider
* pBase
) SAL_THROW(())
168 if (rType
== ::getCppuType( (const Reference
< XInterface
> *)0 ))
169 return Any( &pBase
, ::getCppuType( (const Reference
< XInterface
> *)0 ) );
170 for ( sal_Int32 nPos
= 0; nPos
< nType2Offset
; ++nPos
)
172 const Type_Offset
& rTO
= arType2Offset
[nPos
];
173 typelib_InterfaceTypeDescription
* pTD
= rTO
.pTD
;
176 if (td_equals( (typelib_TypeDescription
*)pTD
,
177 *(typelib_TypeDescriptionReference
**)&rType
))
179 void * pInterface
= (char *)pBase
+ rTO
.nOffset
;
180 return Any( &pInterface
, (typelib_TypeDescription
*)pTD
);
182 pTD
= pTD
->pBaseTypeDescription
;
185 if (rType
== ::getCppuType( (const Reference
< lang::XTypeProvider
> *)0 ))
186 return Any( &pBase
, ::getCppuType( (const Reference
< lang::XTypeProvider
> *)0 ) );
191 //##################################################################################################
192 //##################################################################################################
193 //##################################################################################################
195 // WeakComponentImplHelperBase
196 //__________________________________________________________________________________________________
197 WeakComponentImplHelperBase::WeakComponentImplHelperBase( Mutex
& rMutex
)
202 //__________________________________________________________________________________________________
203 WeakComponentImplHelperBase::~WeakComponentImplHelperBase()
207 //__________________________________________________________________________________________________
208 void WeakComponentImplHelperBase::disposing()
211 //__________________________________________________________________________________________________
212 Any
WeakComponentImplHelperBase::queryInterface( Type
const & rType
)
213 throw (RuntimeException
)
215 if (rType
== ::getCppuType( (Reference
< lang::XComponent
> const *)0 ))
217 void * p
= static_cast< lang::XComponent
* >( this );
218 return Any( &p
, rType
);
220 return OWeakObject::queryInterface( rType
);
222 //__________________________________________________________________________________________________
223 void WeakComponentImplHelperBase::acquire()
226 OWeakObject::acquire();
228 //__________________________________________________________________________________________________
229 void WeakComponentImplHelperBase::release()
232 if (osl_atomic_decrement( &m_refCount
) == 0) {
233 // ensure no other references are created, via the weak connection point, from now on
234 disposeWeakConnectionPoint();
235 // restore reference count:
236 osl_atomic_increment( &m_refCount
);
237 if (! rBHelper
.bDisposed
) {
241 catch (RuntimeException
const& exc
) { // don't break throw ()
244 exc
.Message
, RTL_TEXTENCODING_ASCII_US
).getStr() );
245 static_cast<void>(exc
);
247 OSL_ASSERT( rBHelper
.bDisposed
);
249 OWeakObject::release();
252 //__________________________________________________________________________________________________
253 void WeakComponentImplHelperBase::dispose()
254 throw (RuntimeException
)
256 ClearableMutexGuard
aGuard( rBHelper
.rMutex
);
257 if (!rBHelper
.bDisposed
&& !rBHelper
.bInDispose
)
259 rBHelper
.bInDispose
= sal_True
;
263 // side effect: keeping a reference to this
264 lang::EventObject
aEvt( static_cast< OWeakObject
* >( this ) );
267 rBHelper
.aLC
.disposeAndClear( aEvt
);
272 MutexGuard
aGuard2( rBHelper
.rMutex
);
273 // bDisposed and bInDispose must be set in this order:
274 rBHelper
.bDisposed
= sal_True
;
275 rBHelper
.bInDispose
= sal_False
;
278 MutexGuard
aGuard2( rBHelper
.rMutex
);
279 // bDisposed and bInDispose must be set in this order:
280 rBHelper
.bDisposed
= sal_True
;
281 rBHelper
.bInDispose
= sal_False
;
283 catch (RuntimeException
&)
287 catch (Exception
& exc
)
289 throw RuntimeException(
291 "unexpected UNO exception caught: ") +
292 exc
.Message
, Reference
< XInterface
>() );
296 //__________________________________________________________________________________________________
297 void WeakComponentImplHelperBase::addEventListener(
298 Reference
< lang::XEventListener
> const & xListener
)
299 throw (RuntimeException
)
301 ClearableMutexGuard
aGuard( rBHelper
.rMutex
);
302 if (rBHelper
.bDisposed
|| rBHelper
.bInDispose
)
305 lang::EventObject
aEvt( static_cast< OWeakObject
* >( this ) );
306 xListener
->disposing( aEvt
);
310 rBHelper
.addListener( ::getCppuType( &xListener
), xListener
);
313 //__________________________________________________________________________________________________
314 void WeakComponentImplHelperBase::removeEventListener(
315 Reference
< lang::XEventListener
> const & xListener
)
316 throw (RuntimeException
)
318 rBHelper
.removeListener( ::getCppuType( &xListener
), xListener
);
321 // WeakAggComponentImplHelperBase
322 //__________________________________________________________________________________________________
323 WeakAggComponentImplHelperBase::WeakAggComponentImplHelperBase( Mutex
& rMutex
)
328 //__________________________________________________________________________________________________
329 WeakAggComponentImplHelperBase::~WeakAggComponentImplHelperBase()
333 //__________________________________________________________________________________________________
334 void WeakAggComponentImplHelperBase::disposing()
337 //__________________________________________________________________________________________________
338 Any
WeakAggComponentImplHelperBase::queryInterface( Type
const & rType
)
339 throw (RuntimeException
)
341 return OWeakAggObject::queryInterface( rType
);
343 //__________________________________________________________________________________________________
344 Any
WeakAggComponentImplHelperBase::queryAggregation( Type
const & rType
)
345 throw (RuntimeException
)
347 if (rType
== ::getCppuType( (Reference
< lang::XComponent
> const *)0 ))
349 void * p
= static_cast< lang::XComponent
* >( this );
350 return Any( &p
, rType
);
352 return OWeakAggObject::queryAggregation( rType
);
354 //__________________________________________________________________________________________________
355 void WeakAggComponentImplHelperBase::acquire()
358 OWeakAggObject::acquire();
360 //__________________________________________________________________________________________________
361 void WeakAggComponentImplHelperBase::release()
364 Reference
<XInterface
> const xDelegator_(xDelegator
);
365 if (xDelegator_
.is()) {
366 OWeakAggObject::release();
368 else if (osl_atomic_decrement( &m_refCount
) == 0) {
369 // ensure no other references are created, via the weak connection point, from now on
370 disposeWeakConnectionPoint();
371 // restore reference count:
372 osl_atomic_increment( &m_refCount
);
373 if (! rBHelper
.bDisposed
) {
377 catch (RuntimeException
const& exc
) { // don't break throw ()
380 exc
.Message
, RTL_TEXTENCODING_ASCII_US
).getStr() );
381 static_cast<void>(exc
);
383 OSL_ASSERT( rBHelper
.bDisposed
);
385 OWeakAggObject::release();
388 //__________________________________________________________________________________________________
389 void WeakAggComponentImplHelperBase::dispose()
390 throw (RuntimeException
)
392 ClearableMutexGuard
aGuard( rBHelper
.rMutex
);
393 if (!rBHelper
.bDisposed
&& !rBHelper
.bInDispose
)
395 rBHelper
.bInDispose
= sal_True
;
399 // side effect: keeping a reference to this
400 lang::EventObject
aEvt( static_cast< OWeakObject
* >( this ) );
403 rBHelper
.aLC
.disposeAndClear( aEvt
);
408 MutexGuard
aGuard2( rBHelper
.rMutex
);
409 // bDisposed and bInDispose must be set in this order:
410 rBHelper
.bDisposed
= sal_True
;
411 rBHelper
.bInDispose
= sal_False
;
414 MutexGuard
aGuard2( rBHelper
.rMutex
);
415 // bDisposed and bInDispose must be set in this order:
416 rBHelper
.bDisposed
= sal_True
;
417 rBHelper
.bInDispose
= sal_False
;
419 catch (RuntimeException
&)
423 catch (Exception
& exc
)
425 throw RuntimeException(
427 "unexpected UNO exception caught: ") +
428 exc
.Message
, Reference
< XInterface
>() );
432 //__________________________________________________________________________________________________
433 void WeakAggComponentImplHelperBase::addEventListener(
434 Reference
< lang::XEventListener
> const & xListener
)
435 throw (RuntimeException
)
437 ClearableMutexGuard
aGuard( rBHelper
.rMutex
);
438 if (rBHelper
.bDisposed
|| rBHelper
.bInDispose
)
441 lang::EventObject
aEvt( static_cast< OWeakObject
* >( this ) );
442 xListener
->disposing( aEvt
);
446 rBHelper
.addListener( ::getCppuType( &xListener
), xListener
);
449 //__________________________________________________________________________________________________
450 void WeakAggComponentImplHelperBase::removeEventListener(
451 Reference
< lang::XEventListener
> const & xListener
)
452 throw (RuntimeException
)
454 rBHelper
.removeListener( ::getCppuType( &xListener
), xListener
);
459 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */