LCOV - code coverage report
Current view: top level - cppuhelper/source - interfacecontainer.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 299 360 83.1 %
Date: 2014-04-11 Functions: 29 33 87.9 %
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             : 
      21             : #include <cppuhelper/interfacecontainer.hxx>
      22             : #include <cppuhelper/queryinterface.hxx>
      23             : #include <cppuhelper/propshlp.hxx>
      24             : 
      25             : #include <osl/diagnose.h>
      26             : #include <osl/mutex.hxx>
      27             : 
      28             : #include <boost/unordered_map.hpp>
      29             : 
      30             : #include <com/sun/star/lang/XEventListener.hpp>
      31             : 
      32             : 
      33             : using namespace osl;
      34             : using namespace com::sun::star::uno;
      35             : using namespace com::sun::star::lang;
      36             : 
      37             : namespace cppu
      38             : {
      39             : /**
      40             :  * Reallocate the sequence.
      41             :  */
      42     1755499 : static void realloc( Sequence< Reference< XInterface > > & rSeq, sal_Int32 nNewLen )
      43             :     SAL_THROW(())
      44             : {
      45     1755499 :     rSeq.realloc( nNewLen );
      46     1755499 : }
      47             : 
      48             : /**
      49             :  * Remove an element from an interface sequence.
      50             :  */
      51     2614455 : static void sequenceRemoveElementAt( Sequence< Reference< XInterface > > & rSeq, sal_Int32 index )
      52             :     SAL_THROW(())
      53             : {
      54     2614455 :     sal_Int32 nNewLen = rSeq.getLength() - 1;
      55             : 
      56     2614455 :     Sequence< Reference< XInterface > > aDestSeq( rSeq.getLength() - 1 );
      57             :     // getArray on a const sequence is faster
      58     2614455 :     const Reference< XInterface > * pSource = ((const Sequence< Reference< XInterface > > &)rSeq).getConstArray();
      59     2614455 :     Reference< XInterface > * pDest = aDestSeq.getArray();
      60     2614455 :     sal_Int32 i = 0;
      61     6186590 :     for( ; i < index; i++ )
      62     3572135 :         pDest[i] = pSource[i];
      63     6507034 :     for( sal_Int32 j = i ; j < nNewLen; j++ )
      64     3892579 :         pDest[j] = pSource[j+1];
      65     2614455 :     rSeq = aDestSeq;
      66     2614455 : }
      67             : 
      68             : #ifdef _MSC_VER
      69             : #pragma warning( disable: 4786 )
      70             : #endif
      71             : 
      72     2106056 : OInterfaceIteratorHelper::OInterfaceIteratorHelper( OInterfaceContainerHelper & rCont_ )
      73             :     SAL_THROW(())
      74     2106056 :     : rCont( rCont_ )
      75             : {
      76     2106056 :     MutexGuard aGuard( rCont.rMutex );
      77     2106057 :     if( rCont.bInUse )
      78             :         // worst case, two iterators at the same time
      79         111 :         rCont.copyAndResetInUse();
      80     2106057 :     bIsList = rCont_.bIsList;
      81     2106057 :     aData = rCont_.aData;
      82     2106057 :     if( bIsList )
      83             :     {
      84       79637 :         rCont.bInUse = sal_True;
      85       79637 :         nRemain = aData.pAsSequence->getLength();
      86             :     }
      87     2026420 :     else if( aData.pAsInterface )
      88             :     {
      89     1280323 :         aData.pAsInterface->acquire();
      90     1280323 :         nRemain = 1;
      91             :     }
      92             :     else
      93      746097 :         nRemain = 0;
      94     2106057 : }
      95             : 
      96     2106054 : OInterfaceIteratorHelper::~OInterfaceIteratorHelper() SAL_THROW(())
      97             : {
      98             :     bool bShared;
      99             :     {
     100     2106054 :     MutexGuard aGuard( rCont.rMutex );
     101             :     // bResetInUse protect the iterator against recursion
     102     2106054 :     bShared = aData.pAsSequence == rCont.aData.pAsSequence && rCont.bIsList;
     103     2106054 :     if( bShared )
     104             :     {
     105             :         OSL_ENSURE( rCont.bInUse, "OInterfaceContainerHelper must be in use" );
     106       54759 :         rCont.bInUse = sal_False;
     107     2106054 :     }
     108             :     }
     109             : 
     110     2106054 :     if( !bShared )
     111             :     {
     112     2051295 :         if( bIsList )
     113             :             // Sequence owned by the iterator
     114       24875 :             delete aData.pAsSequence;
     115     2026420 :         else if( aData.pAsInterface )
     116             :             // Interface is acquired by the iterator
     117     1280323 :             aData.pAsInterface->release();
     118             :     }
     119     2106054 : }
     120             : 
     121     1579568 : XInterface * OInterfaceIteratorHelper::next() SAL_THROW(())
     122             : {
     123     1579568 :     if( nRemain )
     124             :     {
     125     1579568 :         nRemain--;
     126     1579568 :         if( bIsList )
     127             :             // typecase to const,so the getArray method is faster
     128      299254 :             return aData.pAsSequence->getConstArray()[nRemain].get();
     129     1280314 :         else if( aData.pAsInterface )
     130     1280314 :             return aData.pAsInterface;
     131             :     }
     132             :     // exception
     133           0 :     return 0;
     134             : }
     135             : 
     136          14 : void OInterfaceIteratorHelper::remove() SAL_THROW(())
     137             : {
     138          14 :     if( bIsList )
     139             :     {
     140             :         OSL_ASSERT( nRemain >= 0 &&
     141             :                     nRemain < aData.pAsSequence->getLength() );
     142           5 :         XInterface * p = aData.pAsSequence->getConstArray()[nRemain].get();
     143           5 :         rCont.removeInterface( * reinterpret_cast< const Reference< XInterface > * >( &p ) );
     144             :     }
     145             :     else
     146             :     {
     147             :         OSL_ASSERT( 0 == nRemain );
     148           9 :         rCont.removeInterface( * reinterpret_cast< const Reference< XInterface > * >(&aData.pAsInterface));
     149             :     }
     150          14 : }
     151             : 
     152     1990302 : OInterfaceContainerHelper::OInterfaceContainerHelper( Mutex & rMutex_ ) SAL_THROW(())
     153             :     : rMutex( rMutex_ )
     154             :     , bInUse( sal_False )
     155     1990302 :     , bIsList( sal_False )
     156             : {
     157     1990302 : }
     158             : 
     159     1886836 : OInterfaceContainerHelper::~OInterfaceContainerHelper() SAL_THROW(())
     160             : {
     161             :     OSL_ENSURE( !bInUse, "~OInterfaceContainerHelper but is in use" );
     162     1886836 :     if( bIsList )
     163          27 :         delete aData.pAsSequence;
     164     1886809 :     else if( aData.pAsInterface )
     165       10615 :         aData.pAsInterface->release();
     166     1886836 : }
     167             : 
     168      369172 : sal_Int32 OInterfaceContainerHelper::getLength() const SAL_THROW(())
     169             : {
     170      369172 :     MutexGuard aGuard( rMutex );
     171      369172 :     if( bIsList )
     172       18867 :         return aData.pAsSequence->getLength();
     173      350305 :     else if( aData.pAsInterface )
     174       37678 :         return 1;
     175      312627 :     return 0;
     176             : }
     177             : 
     178       10115 : Sequence< Reference<XInterface> > OInterfaceContainerHelper::getElements() const SAL_THROW(())
     179             : {
     180       10115 :     MutexGuard aGuard( rMutex );
     181       10115 :     if( bIsList )
     182        1814 :         return *aData.pAsSequence;
     183        8301 :     else if( aData.pAsInterface )
     184             :     {
     185        7759 :         Reference<XInterface> x( aData.pAsInterface );
     186        7759 :         return Sequence< Reference< XInterface > >( &x, 1 );
     187             :     }
     188         542 :     return Sequence< Reference< XInterface > >();
     189             : }
     190             : 
     191       15205 : void OInterfaceContainerHelper::copyAndResetInUse() SAL_THROW(())
     192             : {
     193             :     OSL_ENSURE( bInUse, "OInterfaceContainerHelper not in use" );
     194       15205 :     if( bInUse )
     195             :     {
     196             :         // this should be the worst case. If a iterator is active
     197             :         // and a new Listener is added.
     198       15205 :         if( bIsList )
     199       15205 :             aData.pAsSequence = new Sequence< Reference< XInterface > >( *aData.pAsSequence );
     200           0 :         else if( aData.pAsInterface )
     201           0 :             aData.pAsInterface->acquire();
     202             : 
     203       15205 :         bInUse = sal_False;
     204             :     }
     205       15205 : }
     206             : 
     207     3942921 : sal_Int32 OInterfaceContainerHelper::addInterface( const Reference<XInterface> & rListener ) SAL_THROW(())
     208             : {
     209             :     OSL_ASSERT( rListener.is() );
     210     3942921 :     MutexGuard aGuard( rMutex );
     211     3942921 :     if( bInUse )
     212        1766 :         copyAndResetInUse();
     213             : 
     214     3942921 :     if( bIsList )
     215             :     {
     216     1755499 :         sal_Int32 nLen = aData.pAsSequence->getLength();
     217     1755499 :         realloc( *aData.pAsSequence, nLen +1 );
     218     1755499 :         aData.pAsSequence->getArray()[ nLen ] = rListener;
     219     1755499 :         return nLen +1;
     220             :     }
     221     2187422 :     else if( aData.pAsInterface )
     222             :     {
     223      883755 :         Sequence< Reference< XInterface > > * pSeq = new Sequence< Reference< XInterface > >( 2 );
     224      883755 :         Reference<XInterface> * pArray = pSeq->getArray();
     225      883755 :         pArray[0] = aData.pAsInterface;
     226      883755 :         pArray[1] = rListener;
     227      883755 :         aData.pAsInterface->release();
     228      883755 :         aData.pAsSequence = pSeq;
     229      883755 :         bIsList = sal_True;
     230      883755 :         return 2;
     231             :     }
     232             :     else
     233             :     {
     234     1303667 :         aData.pAsInterface = rListener.get();
     235     1303667 :         if( rListener.is() )
     236     1303667 :             rListener->acquire();
     237     1303667 :         return 1;
     238     3942921 :     }
     239             : }
     240             : 
     241     3827438 : sal_Int32 OInterfaceContainerHelper::removeInterface( const Reference<XInterface> & rListener ) SAL_THROW(())
     242             : {
     243             :     OSL_ASSERT( rListener.is() );
     244     3827438 :     MutexGuard aGuard( rMutex );
     245     3827438 :     if( bInUse )
     246       13328 :         copyAndResetInUse();
     247             : 
     248     3827438 :     if( bIsList )
     249             :     {
     250     2618988 :         const Reference<XInterface> * pL = aData.pAsSequence->getConstArray();
     251     2618988 :         sal_Int32 nLen = aData.pAsSequence->getLength();
     252             :         sal_Int32 i;
     253     6216256 :         for( i = 0; i < nLen; i++ )
     254             :         {
     255             :             // It is not valid to compare the Pointer direkt, but is is is much
     256             :             // more faster.
     257     6211722 :             if( pL[i].get() == rListener.get() )
     258             :             {
     259     2614454 :                 sequenceRemoveElementAt( *aData.pAsSequence, i );
     260     2614454 :                 break;
     261             :             }
     262             :         }
     263             : 
     264     2618988 :         if( i == nLen )
     265             :         {
     266             :             // interface not found, use the correct compare method
     267       29667 :             for( i = 0; i < nLen; i++ )
     268             :             {
     269       25134 :                 if( pL[i] == rListener )
     270             :                 {
     271           1 :                     sequenceRemoveElementAt(*aData.pAsSequence, i );
     272           1 :                     break;
     273             :                 }
     274             :             }
     275             :         }
     276             : 
     277     2618988 :         if( aData.pAsSequence->getLength() == 1 )
     278             :         {
     279      871683 :             XInterface * p = aData.pAsSequence->getConstArray()[0].get();
     280      871683 :             p->acquire();
     281      871683 :             delete aData.pAsSequence;
     282      871683 :             aData.pAsInterface = p;
     283      871683 :             bIsList = sal_False;
     284      871683 :             return 1;
     285             :         }
     286             :         else
     287     1747305 :             return aData.pAsSequence->getLength();
     288             :     }
     289     1208450 :     else if( aData.pAsInterface && Reference<XInterface>( aData.pAsInterface ) == rListener )
     290             :     {
     291     1205353 :         aData.pAsInterface->release();
     292     1205353 :         aData.pAsInterface = 0;
     293             :     }
     294     1208450 :     return aData.pAsInterface ? 1 : 0;
     295             : }
     296             : 
     297      683072 : void OInterfaceContainerHelper::disposeAndClear( const EventObject & rEvt ) SAL_THROW(())
     298             : {
     299      683072 :     ClearableMutexGuard aGuard( rMutex );
     300     1366144 :     OInterfaceIteratorHelper aIt( *this );
     301             :     // Release container, in case new entries come while disposing
     302             :     OSL_ENSURE( !bIsList || bInUse, "OInterfaceContainerHelper not in use" );
     303      683072 :     if( !bIsList && aData.pAsInterface )
     304       62033 :         aData.pAsInterface->release();
     305             :     // set the member to null, use the iterator to delete the values
     306      683072 :     aData.pAsInterface = NULL;
     307      683072 :     bIsList = sal_False;
     308      683072 :     bInUse = sal_False;
     309      683072 :     aGuard.clear();
     310     1456945 :     while( aIt.hasMoreElements() )
     311             :     {
     312             :         try
     313             :         {
     314       90801 :             Reference<XEventListener > xLst( aIt.next(), UNO_QUERY );
     315       90801 :             if( xLst.is() )
     316       80558 :                 xLst->disposing( rEvt );
     317             :         }
     318        1936 :         catch ( RuntimeException & )
     319             :         {
     320             :             // be robust, if e.g. a remote bridge has disposed already.
     321             :             // there is no way to delegate the error to the caller :o(.
     322             :         }
     323      683072 :     }
     324      683072 : }
     325             : 
     326             : 
     327          20 : void OInterfaceContainerHelper::clear() SAL_THROW(())
     328             : {
     329          20 :     ClearableMutexGuard aGuard( rMutex );
     330          40 :     OInterfaceIteratorHelper aIt( *this );
     331             :     // Release container, in case new entries come while disposing
     332             :     OSL_ENSURE( !bIsList || bInUse, "OInterfaceContainerHelper not in use" );
     333          20 :     if( !bIsList && aData.pAsInterface )
     334           9 :         aData.pAsInterface->release();
     335             :     // set the member to null, use the iterator to delete the values
     336          20 :     aData.pAsInterface = 0;
     337          20 :     bIsList = sal_False;
     338          20 :     bInUse = sal_False;
     339             :     // release mutex before aIt destructor call
     340          40 :     aGuard.clear();
     341          20 : }
     342             : 
     343             : // specialized class for type
     344             : 
     345             : typedef ::std::vector< std::pair < Type , void* > > t_type2ptr;
     346             : 
     347     1290456 : OMultiTypeInterfaceContainerHelper::OMultiTypeInterfaceContainerHelper( Mutex & rMutex_ )
     348             :     SAL_THROW(())
     349     1290456 :     : rMutex( rMutex_ )
     350             : {
     351     1290456 :     m_pMap = new t_type2ptr();
     352     1290456 : }
     353     1212292 : OMultiTypeInterfaceContainerHelper::~OMultiTypeInterfaceContainerHelper()
     354             :     SAL_THROW(())
     355             : {
     356     1212292 :     t_type2ptr * pMap = (t_type2ptr *)m_pMap;
     357     1212292 :     t_type2ptr::iterator iter = pMap->begin();
     358     1212292 :     t_type2ptr::iterator end = pMap->end();
     359             : 
     360     2521151 :     while( iter != end )
     361             :     {
     362       96567 :         delete (OInterfaceContainerHelper*)(*iter).second;
     363       96567 :         (*iter).second = 0;
     364       96567 :         ++iter;
     365             :     }
     366     1212292 :     delete pMap;
     367     1212292 : }
     368           0 : Sequence< Type > OMultiTypeInterfaceContainerHelper::getContainedTypes() const
     369             :     SAL_THROW(())
     370             : {
     371           0 :     t_type2ptr * pMap = (t_type2ptr *)m_pMap;
     372             :     t_type2ptr::size_type nSize;
     373             : 
     374           0 :     ::osl::MutexGuard aGuard( rMutex );
     375           0 :     nSize = pMap->size();
     376           0 :     if( nSize )
     377             :     {
     378           0 :         ::com::sun::star::uno::Sequence< Type > aInterfaceTypes( nSize );
     379           0 :         Type * pArray = aInterfaceTypes.getArray();
     380             : 
     381           0 :         t_type2ptr::iterator iter = pMap->begin();
     382           0 :         t_type2ptr::iterator end = pMap->end();
     383             : 
     384           0 :         sal_Int32 i = 0;
     385           0 :         while( iter != end )
     386             :         {
     387             :             // are interfaces added to this container?
     388           0 :             if( ((OInterfaceContainerHelper*)(*iter).second)->getLength() )
     389             :                 // yes, put the type in the array
     390           0 :                 pArray[i++] = (*iter).first;
     391           0 :             ++iter;
     392             :         }
     393           0 :         if( (t_type2ptr::size_type)i != nSize ) {
     394             :             // may be empty container, reduce the sequence to the right size
     395           0 :             aInterfaceTypes = ::com::sun::star::uno::Sequence< Type >( pArray, i );
     396             :         }
     397           0 :         return aInterfaceTypes;
     398             :     }
     399           0 :     return ::com::sun::star::uno::Sequence< Type >();
     400             : }
     401             : 
     402     1129097 : static t_type2ptr::iterator findType(t_type2ptr *pMap, const Type & rKey )
     403             : {
     404     1129097 :     t_type2ptr::iterator iter = pMap->begin();
     405     1129097 :     t_type2ptr::iterator end = pMap->end();
     406             : 
     407     2772621 :     while( iter != end )
     408             :     {
     409     1103728 :         if (iter->first == rKey)
     410      589301 :             break;
     411      514427 :         ++iter;
     412             :     }
     413     1129097 :     return iter;
     414             : }
     415             : 
     416      734177 : OInterfaceContainerHelper * OMultiTypeInterfaceContainerHelper::getContainer( const Type & rKey ) const
     417             :     SAL_THROW(())
     418             : {
     419      734177 :     ::osl::MutexGuard aGuard( rMutex );
     420             : 
     421      734177 :     t_type2ptr * pMap = (t_type2ptr *)m_pMap;
     422      734177 :      t_type2ptr::iterator iter = findType( pMap, rKey );
     423      734177 :     if( iter != pMap->end() )
     424      297675 :             return (OInterfaceContainerHelper*) (*iter).second;
     425      436502 :     return 0;
     426             : }
     427      227675 : sal_Int32 OMultiTypeInterfaceContainerHelper::addInterface(
     428             :     const Type & rKey, const Reference< XInterface > & rListener )
     429             :     SAL_THROW(())
     430             : {
     431      227675 :     ::osl::MutexGuard aGuard( rMutex );
     432      227675 :     t_type2ptr * pMap = (t_type2ptr *)m_pMap;
     433      227675 :     t_type2ptr::iterator iter = findType( pMap, rKey );
     434      227675 :     if( iter == pMap->end() )
     435             :     {
     436      103292 :         OInterfaceContainerHelper * pLC = new OInterfaceContainerHelper( rMutex );
     437      103292 :         pMap->push_back(std::pair<Type, void*>(rKey, pLC));
     438      103292 :         return pLC->addInterface( rListener );
     439             :     }
     440             :     else
     441      124383 :         return ((OInterfaceContainerHelper*)(*iter).second)->addInterface( rListener );
     442             : }
     443      167245 : sal_Int32 OMultiTypeInterfaceContainerHelper::removeInterface(
     444             :     const Type & rKey, const Reference< XInterface > & rListener )
     445             :     SAL_THROW(())
     446             : {
     447      167245 :     ::osl::MutexGuard aGuard( rMutex );
     448             : 
     449             :     // search container with id nUik
     450      167245 :     t_type2ptr * pMap = (t_type2ptr *)m_pMap;
     451      167245 :     t_type2ptr::iterator iter = findType( pMap, rKey );
     452             :         // container found?
     453      167245 :     if( iter != pMap->end() )
     454      167243 :         return ((OInterfaceContainerHelper*)(*iter).second)->removeInterface( rListener );
     455             : 
     456             :     // no container with this id. Always return 0
     457           2 :     return 0;
     458             : }
     459      842399 : void OMultiTypeInterfaceContainerHelper::disposeAndClear( const EventObject & rEvt )
     460             :     SAL_THROW(())
     461             : {
     462      842399 :     t_type2ptr::size_type nSize = 0;
     463      842399 :     OInterfaceContainerHelper ** ppListenerContainers = NULL;
     464             :     {
     465      842399 :         ::osl::MutexGuard aGuard( rMutex );
     466      842399 :         t_type2ptr * pMap = (t_type2ptr *)m_pMap;
     467      842399 :         nSize = pMap->size();
     468      842399 :         if( nSize )
     469             :         {
     470             :             typedef OInterfaceContainerHelper* ppp;
     471       45921 :             ppListenerContainers = new ppp[nSize];
     472             :             //ppListenerContainers = new (ListenerContainer*)[nSize];
     473             : 
     474       45921 :             t_type2ptr::iterator iter = pMap->begin();
     475       45921 :             t_type2ptr::iterator end = pMap->end();
     476             : 
     477       45921 :             t_type2ptr::size_type i = 0;
     478      164323 :             while( iter != end )
     479             :             {
     480       72481 :                 ppListenerContainers[i++] = (OInterfaceContainerHelper*)(*iter).second;
     481       72481 :                 ++iter;
     482             :             }
     483      842399 :         }
     484             :     }
     485             : 
     486             :     // create a copy, because do not fire event in a guarded section
     487      914880 :     for( t_type2ptr::size_type i = 0;
     488             :             i < nSize; i++ )
     489             :     {
     490       72481 :         if( ppListenerContainers[i] )
     491       72481 :             ppListenerContainers[i]->disposeAndClear( rEvt );
     492             :     }
     493             : 
     494      842399 :     delete [] ppListenerContainers;
     495      842399 : }
     496           0 : void OMultiTypeInterfaceContainerHelper::clear()
     497             :     SAL_THROW(())
     498             : {
     499           0 :     ::osl::MutexGuard aGuard( rMutex );
     500           0 :     t_type2ptr * pMap = (t_type2ptr *)m_pMap;
     501           0 :     t_type2ptr::iterator iter = pMap->begin();
     502           0 :     t_type2ptr::iterator end = pMap->end();
     503             : 
     504           0 :     while( iter != end )
     505             :     {
     506           0 :         ((OInterfaceContainerHelper*)(*iter).second)->clear();
     507           0 :         ++iter;
     508           0 :     }
     509           0 : }
     510             : 
     511             : // specialized class for long
     512             : 
     513             : typedef ::std::vector< std::pair < sal_Int32 , void* > > t_long2ptr;
     514             : 
     515       26568 : static t_long2ptr::iterator findLong(t_long2ptr *pMap, sal_Int32 nKey )
     516             : {
     517       26568 :     t_long2ptr::iterator iter = pMap->begin();
     518       26568 :     t_long2ptr::iterator end = pMap->end();
     519             : 
     520      146851 :     while( iter != end )
     521             :     {
     522      104449 :         if (iter->first == nKey)
     523       10734 :             break;
     524       93715 :         ++iter;
     525             :     }
     526       26568 :     return iter;
     527             : }
     528             : 
     529      419023 : OMultiTypeInterfaceContainerHelperInt32::OMultiTypeInterfaceContainerHelperInt32( Mutex & rMutex_ )
     530             :     SAL_THROW(())
     531             :     : m_pMap( NULL )
     532      419023 :     , rMutex( rMutex_ )
     533             : {
     534             :     // delay pMap allocation until necessary.
     535      419023 : }
     536      414467 : OMultiTypeInterfaceContainerHelperInt32::~OMultiTypeInterfaceContainerHelperInt32()
     537             :     SAL_THROW(())
     538             : {
     539      414467 :     if (!m_pMap)
     540      413035 :         return;
     541             : 
     542        1432 :     t_long2ptr * pMap = (t_long2ptr *)m_pMap;
     543        1432 :     t_long2ptr::iterator iter = pMap->begin();
     544        1432 :     t_long2ptr::iterator end = pMap->end();
     545             : 
     546        7988 :     while( iter != end )
     547             :     {
     548        5124 :         delete (OInterfaceContainerHelper*)(*iter).second;
     549        5124 :         (*iter).second = 0;
     550        5124 :         ++iter;
     551             :     }
     552        1432 :     delete pMap;
     553      414467 : }
     554           0 : Sequence< sal_Int32 > OMultiTypeInterfaceContainerHelperInt32::getContainedTypes() const
     555             :     SAL_THROW(())
     556             : {
     557           0 :     t_long2ptr * pMap = (t_long2ptr *)m_pMap;
     558             :     t_long2ptr::size_type nSize;
     559             : 
     560           0 :     ::osl::MutexGuard aGuard( rMutex );
     561           0 :     nSize = pMap ? pMap->size() : 0;
     562           0 :     if( nSize )
     563             :     {
     564           0 :         ::com::sun::star::uno::Sequence< sal_Int32 > aInterfaceTypes( nSize );
     565           0 :         sal_Int32 * pArray = aInterfaceTypes.getArray();
     566             : 
     567           0 :         t_long2ptr::iterator iter = pMap->begin();
     568           0 :         t_long2ptr::iterator end = pMap->end();
     569             : 
     570           0 :         sal_Int32 i = 0;
     571           0 :         while( iter != end )
     572             :         {
     573             :             // are interfaces added to this container?
     574           0 :             if( ((OInterfaceContainerHelper*)(*iter).second)->getLength() )
     575             :                 // yes, put the type in the array
     576           0 :                 pArray[i++] = (*iter).first;
     577           0 :             ++iter;
     578             :         }
     579           0 :         if( (t_long2ptr::size_type)i != nSize ) {
     580             :             // may be empty container, reduce the sequence to the right size
     581           0 :             aInterfaceTypes = ::com::sun::star::uno::Sequence< sal_Int32 >( pArray, i );
     582             :         }
     583           0 :         return aInterfaceTypes;
     584             :     }
     585           0 :     return ::com::sun::star::uno::Sequence< sal_Int32 >();
     586             : }
     587       52533 : OInterfaceContainerHelper * OMultiTypeInterfaceContainerHelperInt32::getContainer( const sal_Int32 & rKey ) const
     588             :     SAL_THROW(())
     589             : {
     590       52533 :     ::osl::MutexGuard aGuard( rMutex );
     591             : 
     592       52533 :     if (!m_pMap)
     593       39171 :         return 0;
     594       13362 :     t_long2ptr * pMap = (t_long2ptr *)m_pMap;
     595       13362 :      t_long2ptr::iterator iter = findLong( pMap, rKey );
     596       13362 :     if( iter != pMap->end() )
     597        2878 :             return (OInterfaceContainerHelper*) (*iter).second;
     598       10484 :     return 0;
     599             : }
     600        8243 : sal_Int32 OMultiTypeInterfaceContainerHelperInt32::addInterface(
     601             :     const sal_Int32 & rKey, const Reference< XInterface > & rListener )
     602             :     SAL_THROW(())
     603             : {
     604        8243 :     ::osl::MutexGuard aGuard( rMutex );
     605        8243 :     if (!m_pMap)
     606        1509 :         m_pMap = new t_long2ptr();
     607        8243 :     t_long2ptr * pMap = (t_long2ptr *)m_pMap;
     608        8243 :     t_long2ptr::iterator iter = findLong( pMap, rKey );
     609        8243 :      if( iter == pMap->end() )
     610             :     {
     611        5343 :         OInterfaceContainerHelper * pLC = new OInterfaceContainerHelper( rMutex );
     612        5343 :         pMap->push_back(std::pair< sal_Int32, void* >(rKey, pLC));
     613        5343 :         return pLC->addInterface( rListener );
     614             :     }
     615             :     else
     616        2900 :         return ((OInterfaceContainerHelper*)(*iter).second)->addInterface( rListener );
     617             : }
     618        4963 : sal_Int32 OMultiTypeInterfaceContainerHelperInt32::removeInterface(
     619             :     const sal_Int32 & rKey, const Reference< XInterface > & rListener )
     620             :     SAL_THROW(())
     621             : {
     622        4963 :     ::osl::MutexGuard aGuard( rMutex );
     623             : 
     624        4963 :     if (!m_pMap)
     625           0 :         return 0;
     626             :     // search container with id nUik
     627        4963 :     t_long2ptr * pMap = (t_long2ptr *)m_pMap;
     628        4963 :     t_long2ptr::iterator iter = findLong( pMap, rKey );
     629             :         // container found?
     630        4963 :     if( iter != pMap->end() )
     631        4956 :         return ((OInterfaceContainerHelper*)(*iter).second)->removeInterface( rListener );
     632             : 
     633             :     // no container with this id. Always return 0
     634           7 :     return 0;
     635             : }
     636       11548 : void OMultiTypeInterfaceContainerHelperInt32::disposeAndClear( const EventObject & rEvt )
     637             :     SAL_THROW(())
     638             : {
     639       11548 :     t_long2ptr::size_type nSize = 0;
     640       11548 :     OInterfaceContainerHelper ** ppListenerContainers = NULL;
     641             :     {
     642       11548 :         ::osl::MutexGuard aGuard( rMutex );
     643       11548 :         if (!m_pMap)
     644       21765 :             return;
     645             : 
     646        1331 :         t_long2ptr * pMap = (t_long2ptr *)m_pMap;
     647        1331 :         nSize = pMap->size();
     648        1331 :         if( nSize )
     649             :         {
     650             :             typedef OInterfaceContainerHelper* ppp;
     651        1331 :             ppListenerContainers = new ppp[nSize];
     652             : 
     653        1331 :             t_long2ptr::iterator iter = pMap->begin();
     654        1331 :             t_long2ptr::iterator end = pMap->end();
     655             : 
     656        1331 :             t_long2ptr::size_type i = 0;
     657        7380 :             while( iter != end )
     658             :             {
     659        4718 :                 ppListenerContainers[i++] = (OInterfaceContainerHelper*)(*iter).second;
     660        4718 :                 ++iter;
     661             :             }
     662        1331 :         }
     663             :     }
     664             : 
     665             :     // create a copy, because do not fire event in a guarded section
     666        6049 :     for( t_long2ptr::size_type i = 0;
     667             :             i < nSize; i++ )
     668             :     {
     669        4718 :         if( ppListenerContainers[i] )
     670        4718 :             ppListenerContainers[i]->disposeAndClear( rEvt );
     671             :     }
     672             : 
     673        1331 :     delete [] ppListenerContainers;
     674             : }
     675           0 : void OMultiTypeInterfaceContainerHelperInt32::clear()
     676             :     SAL_THROW(())
     677             : {
     678           0 :     ::osl::MutexGuard aGuard( rMutex );
     679           0 :     if (!m_pMap)
     680           0 :         return;
     681           0 :     t_long2ptr * pMap = (t_long2ptr *)m_pMap;
     682           0 :     t_long2ptr::iterator iter = pMap->begin();
     683           0 :     t_long2ptr::iterator end = pMap->end();
     684             : 
     685           0 :     while( iter != end )
     686             :     {
     687           0 :         ((OInterfaceContainerHelper*)(*iter).second)->clear();
     688           0 :         ++iter;
     689           0 :     }
     690             : }
     691             : 
     692             : }
     693             : 
     694             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10