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

Generated by: LCOV version 1.10