Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
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.
15 : : *
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).
21 : : *
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.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <cppuhelper/implbase.hxx>
30 : : #include <cppuhelper/compbase.hxx>
31 : : #include <osl/diagnose.h>
32 : : #include <rtl/instance.hxx>
33 : : #include <rtl/uuid.h>
34 : :
35 : : #include <com/sun/star/lang/XComponent.hpp>
36 : : #include "com/sun/star/uno/RuntimeException.hpp"
37 : :
38 : : using namespace ::osl;
39 : : using namespace ::rtl;
40 : : using namespace ::com::sun::star;
41 : : using namespace ::com::sun::star::uno;
42 : :
43 : : namespace
44 : : {
45 : : class theImplHelperInitMutex : public rtl::Static<Mutex, theImplHelperInitMutex>{};
46 : : }
47 : :
48 : : namespace cppu
49 : : {
50 : : //==================================================================================================
51 : 42982 : Mutex & SAL_CALL getImplHelperInitMutex(void) SAL_THROW(())
52 : : {
53 : 42982 : return theImplHelperInitMutex::get();
54 : : }
55 : :
56 : : // ClassDataBase
57 : : //__________________________________________________________________________________________________
58 : 0 : ClassDataBase::ClassDataBase() SAL_THROW(())
59 : : : bOffsetsInit( sal_False )
60 : : , nType2Offset( 0 )
61 : : , nClassCode( 0 )
62 : : , pTypes( 0 )
63 : 0 : , pId( 0 )
64 : : {
65 : 0 : }
66 : : //__________________________________________________________________________________________________
67 : 0 : ClassDataBase::ClassDataBase( sal_Int32 nClassCode_ ) SAL_THROW(())
68 : : : bOffsetsInit( sal_False )
69 : : , nType2Offset( 0 )
70 : : , nClassCode( nClassCode_ )
71 : : , pTypes( 0 )
72 : 0 : , pId( 0 )
73 : : {
74 : 0 : }
75 : : //__________________________________________________________________________________________________
76 : 0 : ClassDataBase::~ClassDataBase() SAL_THROW(())
77 : : {
78 [ # # ]: 0 : delete pTypes;
79 [ # # ]: 0 : delete pId;
80 : :
81 [ # # ]: 0 : for ( sal_Int32 nPos = nType2Offset; nPos--; )
82 : : {
83 : : typelib_typedescription_release(
84 : 0 : (typelib_TypeDescription *)((ClassData *)this)->arType2Offset[nPos].pTD );
85 : : }
86 : 0 : }
87 : :
88 : : // ClassData
89 : : //__________________________________________________________________________________________________
90 : 0 : void ClassData::writeTypeOffset( const Type & rType, sal_Int32 nOffset ) SAL_THROW(())
91 : : {
92 : 0 : arType2Offset[nType2Offset].nOffset = nOffset;
93 : :
94 : 0 : arType2Offset[nType2Offset].pTD = 0;
95 : : typelib_typedescriptionreference_getDescription(
96 : 0 : (typelib_TypeDescription **)&arType2Offset[nType2Offset].pTD, rType.getTypeLibType() );
97 : :
98 [ # # ]: 0 : if (arType2Offset[nType2Offset].pTD)
99 : 0 : ++nType2Offset;
100 : : #if OSL_DEBUG_LEVEL > 1
101 : : else
102 : : {
103 : : OString msg( "### cannot get type description for " );
104 : : msg += OUStringToOString( rType.getTypeName(), RTL_TEXTENCODING_ASCII_US );
105 : : OSL_FAIL( msg.getStr() );
106 : : }
107 : : #endif
108 : 0 : }
109 : : //__________________________________________________________________________________________________
110 : 0 : void ClassData::initTypeProvider() SAL_THROW(())
111 : : {
112 [ # # ][ # # ]: 0 : ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
113 [ # # ]: 0 : if (! pTypes)
114 : : {
115 : : // create id
116 [ # # ]: 0 : pId = new Sequence< sal_Int8 >( 16 );
117 [ # # ][ # # ]: 0 : rtl_createUuid( (sal_uInt8 *)pId->getArray(), 0, sal_True );
118 : :
119 : : // collect types
120 : : Sequence< Type > * types = new Sequence< Type >(
121 [ # # ][ # # ]: 0 : nType2Offset + 1 + (nClassCode == 4 ? 2 : nClassCode) );
122 [ # # ]: 0 : Type * pTypeAr = types->getArray();
123 : :
124 : : // given types
125 : 0 : sal_Int32 nPos = nType2Offset;
126 [ # # ]: 0 : while (nPos--)
127 : 0 : pTypeAr[nPos] = ((typelib_TypeDescription *)arType2Offset[nPos].pTD)->pWeakRef;
128 : :
129 : : // XTypeProvider
130 [ # # ]: 0 : pTypeAr[nType2Offset] = ::getCppuType( (const Reference< lang::XTypeProvider > *)0 );
131 : :
132 : : // class code extra types: [[XComponent,] XWeak[, XAggregation]]
133 [ # # # # : 0 : switch (nClassCode)
# ]
134 : : {
135 : : case 4:
136 [ # # ]: 0 : pTypeAr[nType2Offset +2] = ::getCppuType( (const Reference< lang::XComponent > *)0 );
137 [ # # ]: 0 : pTypeAr[nType2Offset +1] = ::getCppuType( (const Reference< XWeak > *)0 );
138 : 0 : break;
139 : : case 3:
140 [ # # ]: 0 : pTypeAr[nType2Offset +3] = ::getCppuType( (const Reference< lang::XComponent > *)0 );
141 : : case 2:
142 [ # # ]: 0 : pTypeAr[nType2Offset +2] = ::getCppuType( (const Reference< XAggregation > *)0 );
143 : : case 1:
144 [ # # ]: 0 : pTypeAr[nType2Offset +1] = ::getCppuType( (const Reference< XWeak > *)0 );
145 : : }
146 : :
147 : 0 : pTypes = types;
148 [ # # ]: 0 : }
149 : 0 : }
150 : : //__________________________________________________________________________________________________
151 : 0 : Sequence< Type > ClassData::getTypes() SAL_THROW(())
152 : : {
153 [ # # ]: 0 : if (! pTypes)
154 : 0 : initTypeProvider();
155 : 0 : return *pTypes;
156 : : }
157 : : //__________________________________________________________________________________________________
158 : 0 : Sequence< sal_Int8 > ClassData::getImplementationId() SAL_THROW(())
159 : : {
160 [ # # ]: 0 : if (! pTypes)
161 : 0 : initTypeProvider();
162 : 0 : return *pId;
163 : : }
164 : :
165 : : //--------------------------------------------------------------------------------------------------
166 : 0 : static inline sal_Bool td_equals(
167 : : typelib_TypeDescription * pTD, typelib_TypeDescriptionReference * pType )
168 : : SAL_THROW(())
169 : : {
170 : : return (pTD->pWeakRef == pType ||
171 : : (pTD->pTypeName->length == pType->pTypeName->length &&
172 [ # # ][ # # ]: 0 : rtl_ustr_compare( pTD->pTypeName->buffer, pType->pTypeName->buffer ) == 0));
[ # # ]
173 : : }
174 : : //__________________________________________________________________________________________________
175 : 0 : Any ClassData::query( const Type & rType, lang::XTypeProvider * pBase ) SAL_THROW(())
176 : : {
177 [ # # ]: 0 : if (rType == ::getCppuType( (const Reference< XInterface > *)0 ))
178 : 0 : return Any( &pBase, ::getCppuType( (const Reference< XInterface > *)0 ) );
179 [ # # ]: 0 : for ( sal_Int32 nPos = 0; nPos < nType2Offset; ++nPos )
180 : : {
181 : 0 : const Type_Offset & rTO = arType2Offset[nPos];
182 : 0 : typelib_InterfaceTypeDescription * pTD = rTO.pTD;
183 [ # # ]: 0 : while (pTD)
184 : : {
185 [ # # ]: 0 : if (td_equals( (typelib_TypeDescription *)pTD,
186 : 0 : *(typelib_TypeDescriptionReference **)&rType ))
187 : : {
188 : 0 : void * pInterface = (char *)pBase + rTO.nOffset;
189 : 0 : return Any( &pInterface, (typelib_TypeDescription *)pTD );
190 : : }
191 : 0 : pTD = pTD->pBaseTypeDescription;
192 : : }
193 : : }
194 [ # # ]: 0 : if (rType == ::getCppuType( (const Reference< lang::XTypeProvider > *)0 ))
195 : 0 : return Any( &pBase, ::getCppuType( (const Reference< lang::XTypeProvider > *)0 ) );
196 : :
197 : 0 : return Any();
198 : : }
199 : :
200 : : //##################################################################################################
201 : : //##################################################################################################
202 : : //##################################################################################################
203 : :
204 : : // WeakComponentImplHelperBase
205 : : //__________________________________________________________________________________________________
206 : 852207 : WeakComponentImplHelperBase::WeakComponentImplHelperBase( Mutex & rMutex )
207 : : SAL_THROW(())
208 [ + - ]: 852207 : : rBHelper( rMutex )
209 : : {
210 : 852207 : }
211 : : //__________________________________________________________________________________________________
212 [ + - ]: 847231 : WeakComponentImplHelperBase::~WeakComponentImplHelperBase()
213 : : SAL_THROW(())
214 : : {
215 [ - + ]: 847231 : }
216 : : //__________________________________________________________________________________________________
217 : 751779 : void WeakComponentImplHelperBase::disposing()
218 : : {
219 : 751779 : }
220 : : //__________________________________________________________________________________________________
221 : 301526 : Any WeakComponentImplHelperBase::queryInterface( Type const & rType )
222 : : throw (RuntimeException)
223 : : {
224 [ + + ]: 301526 : if (rType == ::getCppuType( (Reference< lang::XComponent > const *)0 ))
225 : : {
226 : 34339 : void * p = static_cast< lang::XComponent * >( this );
227 : 34339 : return Any( &p, rType );
228 : : }
229 : 301526 : return OWeakObject::queryInterface( rType );
230 : : }
231 : : //__________________________________________________________________________________________________
232 : 14220697 : void WeakComponentImplHelperBase::acquire()
233 : : throw ()
234 : : {
235 : 14220697 : OWeakObject::acquire();
236 : 14220712 : }
237 : : //__________________________________________________________________________________________________
238 : 14175806 : void WeakComponentImplHelperBase::release()
239 : : throw ()
240 : : {
241 [ + + ]: 14175806 : if (osl_decrementInterlockedCount( &m_refCount ) == 0) {
242 : : // ensure no other references are created, via the weak connection point, from now on
243 : 847166 : disposeWeakConnectionPoint();
244 : : // restore reference count:
245 : 847166 : osl_incrementInterlockedCount( &m_refCount );
246 [ + + ]: 847166 : if (! rBHelper.bDisposed) {
247 : : try {
248 [ + - ]: 808625 : dispose();
249 : : }
250 : 0 : catch (RuntimeException const& exc) { // don't break throw ()
251 : : OSL_FAIL(
252 : : OUStringToOString(
253 : : exc.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
254 : : static_cast<void>(exc);
255 : : }
256 : : OSL_ASSERT( rBHelper.bDisposed );
257 : : }
258 : 847166 : OWeakObject::release();
259 : : }
260 [ # # ]: 14175804 : }
261 : : //__________________________________________________________________________________________________
262 : 848569 : void WeakComponentImplHelperBase::dispose()
263 : : throw (RuntimeException)
264 : : {
265 [ + - ]: 848569 : ClearableMutexGuard aGuard( rBHelper.rMutex );
266 [ + + ][ + + ]: 848569 : if (!rBHelper.bDisposed && !rBHelper.bInDispose)
267 : : {
268 : 848024 : rBHelper.bInDispose = sal_True;
269 [ + - ]: 848024 : aGuard.clear();
270 : : try
271 : : {
272 : : // side effect: keeping a reference to this
273 [ + - ][ + - ]: 848024 : lang::EventObject aEvt( static_cast< OWeakObject * >( this ) );
274 : : try
275 : : {
276 [ + - ]: 848024 : rBHelper.aLC.disposeAndClear( aEvt );
277 [ + - ]: 848024 : disposing();
278 : : }
279 : 0 : catch (...)
280 : : {
281 [ # # ]: 0 : MutexGuard aGuard2( rBHelper.rMutex );
282 : : // bDisposed and bInDispose must be set in this order:
283 : 0 : rBHelper.bDisposed = sal_True;
284 : 0 : rBHelper.bInDispose = sal_False;
285 : 0 : throw;
286 : : }
287 [ + - ]: 848024 : MutexGuard aGuard2( rBHelper.rMutex );
288 : : // bDisposed and bInDispose must be set in this order:
289 : 848024 : rBHelper.bDisposed = sal_True;
290 [ + - ][ + - ]: 848024 : rBHelper.bInDispose = sal_False;
291 : : }
292 : 0 : catch (RuntimeException &)
293 : : {
294 : 0 : throw;
295 : : }
296 [ # # # ]: 0 : catch (Exception & exc)
297 : : {
298 : : throw RuntimeException(
299 : : OUString( RTL_CONSTASCII_USTRINGPARAM(
300 : : "unexpected UNO exception caught: ") ) +
301 [ # # # # ]: 0 : exc.Message, Reference< XInterface >() );
302 : : }
303 [ + - ]: 848569 : }
304 : 848564 : }
305 : : //__________________________________________________________________________________________________
306 : 10637 : void WeakComponentImplHelperBase::addEventListener(
307 : : Reference< lang::XEventListener > const & xListener )
308 : : throw (RuntimeException)
309 : : {
310 [ + - ]: 10637 : ClearableMutexGuard aGuard( rBHelper.rMutex );
311 [ + - ][ - + ]: 10637 : if (rBHelper.bDisposed || rBHelper.bInDispose)
312 : : {
313 [ # # ]: 0 : aGuard.clear();
314 [ # # ][ # # ]: 0 : lang::EventObject aEvt( static_cast< OWeakObject * >( this ) );
315 [ # # ][ # # ]: 0 : xListener->disposing( aEvt );
[ # # ]
316 : : }
317 : : else
318 : : {
319 [ + - ][ + - ]: 10637 : rBHelper.addListener( ::getCppuType( &xListener ), xListener );
320 [ + - ]: 10637 : }
321 : 10637 : }
322 : : //__________________________________________________________________________________________________
323 : 7447 : void WeakComponentImplHelperBase::removeEventListener(
324 : : Reference< lang::XEventListener > const & xListener )
325 : : throw (RuntimeException)
326 : : {
327 : 7447 : rBHelper.removeListener( ::getCppuType( &xListener ), xListener );
328 : 7447 : }
329 : :
330 : : // WeakAggComponentImplHelperBase
331 : : //__________________________________________________________________________________________________
332 : 6463 : WeakAggComponentImplHelperBase::WeakAggComponentImplHelperBase( Mutex & rMutex )
333 : : SAL_THROW(())
334 [ + - ]: 6463 : : rBHelper( rMutex )
335 : : {
336 : 6463 : }
337 : : //__________________________________________________________________________________________________
338 [ + - ]: 6151 : WeakAggComponentImplHelperBase::~WeakAggComponentImplHelperBase()
339 : : SAL_THROW(())
340 : : {
341 [ - + ]: 6151 : }
342 : : //__________________________________________________________________________________________________
343 : 431 : void WeakAggComponentImplHelperBase::disposing()
344 : : {
345 : 431 : }
346 : : //__________________________________________________________________________________________________
347 : 46157 : Any WeakAggComponentImplHelperBase::queryInterface( Type const & rType )
348 : : throw (RuntimeException)
349 : : {
350 : 46157 : return OWeakAggObject::queryInterface( rType );
351 : : }
352 : : //__________________________________________________________________________________________________
353 : 42249 : Any WeakAggComponentImplHelperBase::queryAggregation( Type const & rType )
354 : : throw (RuntimeException)
355 : : {
356 [ + + ]: 42249 : if (rType == ::getCppuType( (Reference< lang::XComponent > const *)0 ))
357 : : {
358 : 7250 : void * p = static_cast< lang::XComponent * >( this );
359 : 7250 : return Any( &p, rType );
360 : : }
361 : 42249 : return OWeakAggObject::queryAggregation( rType );
362 : : }
363 : : //__________________________________________________________________________________________________
364 : 459002 : void WeakAggComponentImplHelperBase::acquire()
365 : : throw ()
366 : : {
367 : 459002 : OWeakAggObject::acquire();
368 : 459002 : }
369 : : //__________________________________________________________________________________________________
370 : 456591 : void WeakAggComponentImplHelperBase::release()
371 : : throw ()
372 : : {
373 [ + - ]: 456591 : Reference<XInterface> const xDelegator_(xDelegator);
374 [ + + ]: 456591 : if (xDelegator_.is()) {
375 : 4768 : OWeakAggObject::release();
376 : : }
377 [ + - ][ + + ]: 451823 : else if (osl_decrementInterlockedCount( &m_refCount ) == 0) {
378 : : // ensure no other references are created, via the weak connection point, from now on
379 [ + - ]: 6151 : disposeWeakConnectionPoint();
380 : : // restore reference count:
381 [ + - ]: 6151 : osl_incrementInterlockedCount( &m_refCount );
382 [ + + ]: 6151 : if (! rBHelper.bDisposed) {
383 : : try {
384 [ + - ]: 203 : dispose();
385 : : }
386 [ # # ]: 0 : catch (RuntimeException const& exc) { // don't break throw ()
387 : : OSL_FAIL(
388 : : OUStringToOString(
389 : : exc.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
390 : : static_cast<void>(exc);
391 : : }
392 : : OSL_ASSERT( rBHelper.bDisposed );
393 : : }
394 : 6151 : OWeakAggObject::release();
395 : 456591 : }
396 [ # # ]: 456591 : }
397 : : //__________________________________________________________________________________________________
398 : 6796 : void WeakAggComponentImplHelperBase::dispose()
399 : : throw (RuntimeException)
400 : : {
401 [ + - ]: 6796 : ClearableMutexGuard aGuard( rBHelper.rMutex );
402 [ + + ][ + + ]: 6796 : if (!rBHelper.bDisposed && !rBHelper.bInDispose)
403 : : {
404 : 6217 : rBHelper.bInDispose = sal_True;
405 [ + - ]: 6217 : aGuard.clear();
406 : : try
407 : : {
408 : : // side effect: keeping a reference to this
409 [ + - ][ + - ]: 6217 : lang::EventObject aEvt( static_cast< OWeakObject * >( this ) );
410 : : try
411 : : {
412 [ + - ]: 6217 : rBHelper.aLC.disposeAndClear( aEvt );
413 [ + - ]: 6217 : disposing();
414 : : }
415 : 0 : catch (...)
416 : : {
417 [ # # ]: 0 : MutexGuard aGuard2( rBHelper.rMutex );
418 : : // bDisposed and bInDispose must be set in this order:
419 : 0 : rBHelper.bDisposed = sal_True;
420 : 0 : rBHelper.bInDispose = sal_False;
421 : 0 : throw;
422 : : }
423 [ + - ]: 6217 : MutexGuard aGuard2( rBHelper.rMutex );
424 : : // bDisposed and bInDispose must be set in this order:
425 : 6217 : rBHelper.bDisposed = sal_True;
426 [ + - ][ + - ]: 6217 : rBHelper.bInDispose = sal_False;
427 : : }
428 : 0 : catch (RuntimeException &)
429 : : {
430 : 0 : throw;
431 : : }
432 [ # # # ]: 0 : catch (Exception & exc)
433 : : {
434 : : throw RuntimeException(
435 : : OUString( RTL_CONSTASCII_USTRINGPARAM(
436 : : "unexpected UNO exception caught: ") ) +
437 [ # # # # ]: 0 : exc.Message, Reference< XInterface >() );
438 : : }
439 [ + - ]: 6796 : }
440 : 6796 : }
441 : : //__________________________________________________________________________________________________
442 : 947 : void WeakAggComponentImplHelperBase::addEventListener(
443 : : Reference< lang::XEventListener > const & xListener )
444 : : throw (RuntimeException)
445 : : {
446 [ + - ]: 947 : ClearableMutexGuard aGuard( rBHelper.rMutex );
447 [ + - ][ - + ]: 947 : if (rBHelper.bDisposed || rBHelper.bInDispose)
448 : : {
449 [ # # ]: 0 : aGuard.clear();
450 [ # # ][ # # ]: 0 : lang::EventObject aEvt( static_cast< OWeakObject * >( this ) );
451 [ # # ][ # # ]: 0 : xListener->disposing( aEvt );
[ # # ]
452 : : }
453 : : else
454 : : {
455 [ + - ][ + - ]: 947 : rBHelper.addListener( ::getCppuType( &xListener ), xListener );
456 [ + - ]: 947 : }
457 : 947 : }
458 : : //__________________________________________________________________________________________________
459 : 102 : void WeakAggComponentImplHelperBase::removeEventListener(
460 : : Reference< lang::XEventListener > const & xListener )
461 : : throw (RuntimeException)
462 : : {
463 : 102 : rBHelper.removeListener( ::getCppuType( &xListener ), xListener );
464 : 102 : }
465 : :
466 : : }
467 : :
468 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|