LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/cppuhelper/source - implbase.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 98 193 50.8 %
Date: 2013-07-09 Functions: 20 31 64.5 %
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       17950 : Mutex & SAL_CALL getImplHelperInitMutex(void) SAL_THROW(())
      43             : {
      44       17950 :     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           0 :     return (pTD->pWeakRef == pType ||
     162           0 :             (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      478179 : WeakComponentImplHelperBase::WeakComponentImplHelperBase( Mutex & rMutex )
     198             :     SAL_THROW(())
     199      478179 :     : rBHelper( rMutex )
     200             : {
     201      478179 : }
     202             : //__________________________________________________________________________________________________
     203      475678 : WeakComponentImplHelperBase::~WeakComponentImplHelperBase()
     204             :     SAL_THROW(())
     205             : {
     206      475678 : }
     207             : //__________________________________________________________________________________________________
     208      414090 : void WeakComponentImplHelperBase::disposing()
     209             : {
     210      414090 : }
     211             : //__________________________________________________________________________________________________
     212      157893 : Any WeakComponentImplHelperBase::queryInterface( Type const & rType )
     213             :     throw (RuntimeException)
     214             : {
     215      157893 :     if (rType == ::getCppuType( (Reference< lang::XComponent > const *)0 ))
     216             :     {
     217       19131 :         void * p = static_cast< lang::XComponent * >( this );
     218       19131 :         return Any( &p, rType );
     219             :     }
     220      138762 :     return OWeakObject::queryInterface( rType );
     221             : }
     222             : //__________________________________________________________________________________________________
     223    11246832 : void WeakComponentImplHelperBase::acquire()
     224             :     throw ()
     225             : {
     226    11246832 :     OWeakObject::acquire();
     227    11246840 : }
     228             : //__________________________________________________________________________________________________
     229    11234555 : void WeakComponentImplHelperBase::release()
     230             :     throw ()
     231             : {
     232    11234555 :     if (osl_atomic_decrement( &m_refCount ) == 0) {
     233             :         // ensure no other references are created, via the weak connection point, from now on
     234      475636 :         disposeWeakConnectionPoint();
     235             :         // restore reference count:
     236      475636 :         osl_atomic_increment( &m_refCount );
     237      475636 :         if (! rBHelper.bDisposed) {
     238             :             try {
     239      455154 :                 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      475636 :         OWeakObject::release();
     250             :     }
     251    11234555 : }
     252             : //__________________________________________________________________________________________________
     253      477007 : void WeakComponentImplHelperBase::dispose()
     254             :     throw (RuntimeException)
     255             : {
     256      477007 :     ClearableMutexGuard aGuard( rBHelper.rMutex );
     257      477007 :     if (!rBHelper.bDisposed && !rBHelper.bInDispose)
     258             :     {
     259      476748 :         rBHelper.bInDispose = sal_True;
     260      476748 :         aGuard.clear();
     261             :         try
     262             :         {
     263             :             // side effect: keeping a reference to this
     264      476748 :             lang::EventObject aEvt( static_cast< OWeakObject * >( this ) );
     265             :             try
     266             :             {
     267      476748 :                 rBHelper.aLC.disposeAndClear( aEvt );
     268      476748 :                 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      953496 :             MutexGuard aGuard2( rBHelper.rMutex );
     279             :             // bDisposed and bInDispose must be set in this order:
     280      476748 :             rBHelper.bDisposed = sal_True;
     281      953496 :             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(
     291           0 :                               "unexpected UNO exception caught: ") +
     292           0 :                 exc.Message, Reference< XInterface >() );
     293             :         }
     294      477007 :     }
     295      477007 : }
     296             : //__________________________________________________________________________________________________
     297        2416 : void WeakComponentImplHelperBase::addEventListener(
     298             :     Reference< lang::XEventListener > const & xListener )
     299             :     throw (RuntimeException)
     300             : {
     301        2416 :     ClearableMutexGuard aGuard( rBHelper.rMutex );
     302        2416 :     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        2416 :         rBHelper.addListener( ::getCppuType( &xListener ), xListener );
     311        2416 :     }
     312        2416 : }
     313             : //__________________________________________________________________________________________________
     314         734 : void WeakComponentImplHelperBase::removeEventListener(
     315             :     Reference< lang::XEventListener > const & xListener )
     316             :     throw (RuntimeException)
     317             : {
     318         734 :     rBHelper.removeListener( ::getCppuType( &xListener ), xListener );
     319         734 : }
     320             : 
     321             : // WeakAggComponentImplHelperBase
     322             : //__________________________________________________________________________________________________
     323        3407 : WeakAggComponentImplHelperBase::WeakAggComponentImplHelperBase( Mutex & rMutex )
     324             :     SAL_THROW(())
     325        3407 :     : rBHelper( rMutex )
     326             : {
     327        3407 : }
     328             : //__________________________________________________________________________________________________
     329        3213 : WeakAggComponentImplHelperBase::~WeakAggComponentImplHelperBase()
     330             :     SAL_THROW(())
     331             : {
     332        3213 : }
     333             : //__________________________________________________________________________________________________
     334         238 : void WeakAggComponentImplHelperBase::disposing()
     335             : {
     336         238 : }
     337             : //__________________________________________________________________________________________________
     338       25858 : Any WeakAggComponentImplHelperBase::queryInterface( Type const & rType )
     339             :     throw (RuntimeException)
     340             : {
     341       25858 :     return OWeakAggObject::queryInterface( rType );
     342             : }
     343             : //__________________________________________________________________________________________________
     344       23764 : Any WeakAggComponentImplHelperBase::queryAggregation( Type const & rType )
     345             :     throw (RuntimeException)
     346             : {
     347       23764 :     if (rType == ::getCppuType( (Reference< lang::XComponent > const *)0 ))
     348             :     {
     349        3723 :         void * p = static_cast< lang::XComponent * >( this );
     350        3723 :         return Any( &p, rType );
     351             :     }
     352       20041 :     return OWeakAggObject::queryAggregation( rType );
     353             : }
     354             : //__________________________________________________________________________________________________
     355      313757 : void WeakAggComponentImplHelperBase::acquire()
     356             :     throw ()
     357             : {
     358      313757 :     OWeakAggObject::acquire();
     359      313757 : }
     360             : //__________________________________________________________________________________________________
     361      312328 : void WeakAggComponentImplHelperBase::release()
     362             :     throw ()
     363             : {
     364      312328 :     Reference<XInterface> const xDelegator_(xDelegator);
     365      312328 :     if (xDelegator_.is()) {
     366        2677 :         OWeakAggObject::release();
     367             :     }
     368      309651 :     else if (osl_atomic_decrement( &m_refCount ) == 0) {
     369             :         // ensure no other references are created, via the weak connection point, from now on
     370        3213 :         disposeWeakConnectionPoint();
     371             :         // restore reference count:
     372        3213 :         osl_atomic_increment( &m_refCount );
     373        3213 :         if (! rBHelper.bDisposed) {
     374             :             try {
     375         115 :                 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        3213 :         OWeakAggObject::release();
     386      312328 :     }
     387      312328 : }
     388             : //__________________________________________________________________________________________________
     389        3540 : void WeakAggComponentImplHelperBase::dispose()
     390             :     throw (RuntimeException)
     391             : {
     392        3540 :     ClearableMutexGuard aGuard( rBHelper.rMutex );
     393        3540 :     if (!rBHelper.bDisposed && !rBHelper.bInDispose)
     394             :     {
     395        3252 :         rBHelper.bInDispose = sal_True;
     396        3252 :         aGuard.clear();
     397             :         try
     398             :         {
     399             :             // side effect: keeping a reference to this
     400        3252 :             lang::EventObject aEvt( static_cast< OWeakObject * >( this ) );
     401             :             try
     402             :             {
     403        3252 :                 rBHelper.aLC.disposeAndClear( aEvt );
     404        3252 :                 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        6504 :             MutexGuard aGuard2( rBHelper.rMutex );
     415             :             // bDisposed and bInDispose must be set in this order:
     416        3252 :             rBHelper.bDisposed = sal_True;
     417        6504 :             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(
     427           0 :                               "unexpected UNO exception caught: ") +
     428           0 :                 exc.Message, Reference< XInterface >() );
     429             :         }
     430        3540 :     }
     431        3540 : }
     432             : //__________________________________________________________________________________________________
     433         513 : void WeakAggComponentImplHelperBase::addEventListener(
     434             :     Reference< lang::XEventListener > const & xListener )
     435             :     throw (RuntimeException)
     436             : {
     437         513 :     ClearableMutexGuard aGuard( rBHelper.rMutex );
     438         513 :     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         513 :         rBHelper.addListener( ::getCppuType( &xListener ), xListener );
     447         513 :     }
     448         513 : }
     449             : //__________________________________________________________________________________________________
     450          50 : void WeakAggComponentImplHelperBase::removeEventListener(
     451             :     Reference< lang::XEventListener > const & xListener )
     452             :     throw (RuntimeException)
     453             : {
     454          50 :     rBHelper.removeListener( ::getCppuType( &xListener ), xListener );
     455          50 : }
     456             : 
     457             : }
     458             : 
     459             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10