LCOV - code coverage report
Current view: top level - libreoffice/cppuhelper/source - implbase.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 89 189 47.1 %
Date: 2012-12-17 Functions: 18 31 58.1 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10