LCOV - code coverage report
Current view: top level - cppuhelper/source - interfacecontainer.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 299 360 83.1 %
Date: 2014-11-03 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/scoped_array.hpp>
      29             : #include <boost/unordered_map.hpp>
      30             : 
      31             : #include <com/sun/star/lang/XEventListener.hpp>
      32             : 
      33             : 
      34             : using namespace osl;
      35             : using namespace com::sun::star::uno;
      36             : using namespace com::sun::star::lang;
      37             : 
      38             : namespace cppu
      39             : {
      40             : /**
      41             :  * Reallocate the sequence.
      42             :  */
      43     5567431 : static void realloc( Sequence< Reference< XInterface > > & rSeq, sal_Int32 nNewLen )
      44             : {
      45     5567431 :     rSeq.realloc( nNewLen );
      46     5567431 : }
      47             : 
      48             : /**
      49             :  * Remove an element from an interface sequence.
      50             :  */
      51     8436626 : static void sequenceRemoveElementAt( Sequence< Reference< XInterface > > & rSeq, sal_Int32 index )
      52             : {
      53     8436626 :     sal_Int32 nNewLen = rSeq.getLength() - 1;
      54             : 
      55     8436626 :     Sequence< Reference< XInterface > > aDestSeq( rSeq.getLength() - 1 );
      56             :     // getArray on a const sequence is faster
      57     8436626 :     const Reference< XInterface > * pSource = ((const Sequence< Reference< XInterface > > &)rSeq).getConstArray();
      58     8436626 :     Reference< XInterface > * pDest = aDestSeq.getArray();
      59     8436626 :     sal_Int32 i = 0;
      60    19124531 :     for( ; i < index; i++ )
      61    10687905 :         pDest[i] = pSource[i];
      62    19840643 :     for( sal_Int32 j = i ; j < nNewLen; j++ )
      63    11404017 :         pDest[j] = pSource[j+1];
      64     8436626 :     rSeq = aDestSeq;
      65     8436626 : }
      66             : 
      67             : #ifdef _MSC_VER
      68             : #pragma warning( disable: 4786 )
      69             : #endif
      70             : 
      71     6302877 : OInterfaceIteratorHelper::OInterfaceIteratorHelper( OInterfaceContainerHelper & rCont_ )
      72     6302877 :     : rCont( rCont_ )
      73             : {
      74     6302877 :     MutexGuard aGuard( rCont.rMutex );
      75     6302877 :     if( rCont.bInUse )
      76             :         // worst case, two iterators at the same time
      77         184 :         rCont.copyAndResetInUse();
      78     6302877 :     bIsList = rCont_.bIsList;
      79     6302877 :     aData = rCont_.aData;
      80     6302877 :     if( bIsList )
      81             :     {
      82      286724 :         rCont.bInUse = sal_True;
      83      286724 :         nRemain = aData.pAsSequence->getLength();
      84             :     }
      85     6016153 :     else if( aData.pAsInterface )
      86             :     {
      87     3679009 :         aData.pAsInterface->acquire();
      88     3679009 :         nRemain = 1;
      89             :     }
      90             :     else
      91     2337144 :         nRemain = 0;
      92     6302877 : }
      93             : 
      94     6302875 : OInterfaceIteratorHelper::~OInterfaceIteratorHelper()
      95             : {
      96             :     bool bShared;
      97             :     {
      98     6302875 :     MutexGuard aGuard( rCont.rMutex );
      99             :     // bResetInUse protect the iterator against recursion
     100     6302875 :     bShared = aData.pAsSequence == rCont.aData.pAsSequence && rCont.bIsList;
     101     6302875 :     if( bShared )
     102             :     {
     103             :         OSL_ENSURE( rCont.bInUse, "OInterfaceContainerHelper must be in use" );
     104      129167 :         rCont.bInUse = sal_False;
     105     6302875 :     }
     106             :     }
     107             : 
     108     6302875 :     if( !bShared )
     109             :     {
     110     6173708 :         if( bIsList )
     111             :             // Sequence owned by the iterator
     112      157555 :             delete aData.pAsSequence;
     113     6016153 :         else if( aData.pAsInterface )
     114             :             // Interface is acquired by the iterator
     115     3679009 :             aData.pAsInterface->release();
     116             :     }
     117     6302875 : }
     118             : 
     119     4605239 : XInterface * OInterfaceIteratorHelper::next()
     120             : {
     121     4605239 :     if( nRemain )
     122             :     {
     123     4605239 :         nRemain--;
     124     4605239 :         if( bIsList )
     125             :             // typecase to const,so the getArray method is faster
     126      926248 :             return aData.pAsSequence->getConstArray()[nRemain].get();
     127     3678991 :         else if( aData.pAsInterface )
     128     3678991 :             return aData.pAsInterface;
     129             :     }
     130             :     // exception
     131           0 :     return 0;
     132             : }
     133             : 
     134          27 : void OInterfaceIteratorHelper::remove()
     135             : {
     136          27 :     if( bIsList )
     137             :     {
     138             :         OSL_ASSERT( nRemain >= 0 &&
     139             :                     nRemain < aData.pAsSequence->getLength() );
     140          10 :         XInterface * p = aData.pAsSequence->getConstArray()[nRemain].get();
     141          10 :         rCont.removeInterface( * reinterpret_cast< const Reference< XInterface > * >( &p ) );
     142             :     }
     143             :     else
     144             :     {
     145             :         OSL_ASSERT( 0 == nRemain );
     146          17 :         rCont.removeInterface( * reinterpret_cast< const Reference< XInterface > * >(&aData.pAsInterface));
     147             :     }
     148          27 : }
     149             : 
     150     5729756 : OInterfaceContainerHelper::OInterfaceContainerHelper( Mutex & rMutex_ )
     151             :     : rMutex( rMutex_ )
     152             :     , bInUse( sal_False )
     153     5729756 :     , bIsList( sal_False )
     154             : {
     155     5729756 : }
     156             : 
     157     5504337 : OInterfaceContainerHelper::~OInterfaceContainerHelper()
     158             : {
     159             :     OSL_ENSURE( !bInUse, "~OInterfaceContainerHelper but is in use" );
     160     5504337 :     if( bIsList )
     161          22 :         delete aData.pAsSequence;
     162     5504315 :     else if( aData.pAsInterface )
     163       36299 :         aData.pAsInterface->release();
     164     5504338 : }
     165             : 
     166     1187822 : sal_Int32 OInterfaceContainerHelper::getLength() const
     167             : {
     168     1187822 :     MutexGuard aGuard( rMutex );
     169     1187822 :     if( bIsList )
     170       42520 :         return aData.pAsSequence->getLength();
     171     1145302 :     else if( aData.pAsInterface )
     172       95875 :         return 1;
     173     1049427 :     return 0;
     174             : }
     175             : 
     176       23511 : Sequence< Reference<XInterface> > OInterfaceContainerHelper::getElements() const
     177             : {
     178       23511 :     MutexGuard aGuard( rMutex );
     179       23511 :     if( bIsList )
     180        2388 :         return *aData.pAsSequence;
     181       21123 :     else if( aData.pAsInterface )
     182             :     {
     183       19517 :         Reference<XInterface> x( aData.pAsInterface );
     184       19517 :         return Sequence< Reference< XInterface > >( &x, 1 );
     185             :     }
     186        1606 :     return Sequence< Reference< XInterface > >();
     187             : }
     188             : 
     189      130785 : void OInterfaceContainerHelper::copyAndResetInUse()
     190             : {
     191             :     OSL_ENSURE( bInUse, "OInterfaceContainerHelper not in use" );
     192      130785 :     if( bInUse )
     193             :     {
     194             :         // this should be the worst case. If a iterator is active
     195             :         // and a new Listener is added.
     196      130785 :         if( bIsList )
     197      130785 :             aData.pAsSequence = new Sequence< Reference< XInterface > >( *aData.pAsSequence );
     198           0 :         else if( aData.pAsInterface )
     199           0 :             aData.pAsInterface->acquire();
     200             : 
     201      130785 :         bInUse = sal_False;
     202             :     }
     203      130785 : }
     204             : 
     205    12289630 : sal_Int32 OInterfaceContainerHelper::addInterface( const Reference<XInterface> & rListener )
     206             : {
     207             :     OSL_ASSERT( rListener.is() );
     208    12289630 :     MutexGuard aGuard( rMutex );
     209    12289630 :     if( bInUse )
     210        4777 :         copyAndResetInUse();
     211             : 
     212    12289630 :     if( bIsList )
     213             :     {
     214     5567431 :         sal_Int32 nLen = aData.pAsSequence->getLength();
     215     5567431 :         realloc( *aData.pAsSequence, nLen +1 );
     216     5567431 :         aData.pAsSequence->getArray()[ nLen ] = rListener;
     217     5567431 :         return nLen +1;
     218             :     }
     219     6722199 :     else if( aData.pAsInterface )
     220             :     {
     221     2925209 :         Sequence< Reference< XInterface > > * pSeq = new Sequence< Reference< XInterface > >( 2 );
     222     2925209 :         Reference<XInterface> * pArray = pSeq->getArray();
     223     2925209 :         pArray[0] = aData.pAsInterface;
     224     2925209 :         pArray[1] = rListener;
     225     2925209 :         aData.pAsInterface->release();
     226     2925209 :         aData.pAsSequence = pSeq;
     227     2925209 :         bIsList = sal_True;
     228     2925209 :         return 2;
     229             :     }
     230             :     else
     231             :     {
     232     3796990 :         aData.pAsInterface = rListener.get();
     233     3796990 :         if( rListener.is() )
     234     3796990 :             rListener->acquire();
     235     3796990 :         return 1;
     236    12289630 :     }
     237             : }
     238             : 
     239    12008560 : sal_Int32 OInterfaceContainerHelper::removeInterface( const Reference<XInterface> & rListener )
     240             : {
     241             :     OSL_ASSERT( rListener.is() );
     242    12008560 :     MutexGuard aGuard( rMutex );
     243    12008560 :     if( bInUse )
     244      125824 :         copyAndResetInUse();
     245             : 
     246    12008560 :     if( bIsList )
     247             :     {
     248     8448525 :         const Reference<XInterface> * pL = aData.pAsSequence->getConstArray();
     249     8448525 :         sal_Int32 nLen = aData.pAsSequence->getLength();
     250             :         sal_Int32 i;
     251    19215525 :         for( i = 0; i < nLen; i++ )
     252             :         {
     253             :             // It is not valid to compare the Pointer direkt, but is is is much
     254             :             // more faster.
     255    19203622 :             if( pL[i].get() == rListener.get() )
     256             :             {
     257     8436624 :                 sequenceRemoveElementAt( *aData.pAsSequence, i );
     258     8436624 :                 break;
     259             :             }
     260             :         }
     261             : 
     262     8448527 :         if( i == nLen )
     263             :         {
     264             :             // interface not found, use the correct compare method
     265       90996 :             for( i = 0; i < nLen; i++ )
     266             :             {
     267       79097 :                 if( pL[i] == rListener )
     268             :                 {
     269           2 :                     sequenceRemoveElementAt(*aData.pAsSequence, i );
     270           2 :                     break;
     271             :                 }
     272             :             }
     273             :         }
     274             : 
     275     8448527 :         if( aData.pAsSequence->getLength() == 1 )
     276             :         {
     277     2896508 :             XInterface * p = aData.pAsSequence->getConstArray()[0].get();
     278     2896508 :             p->acquire();
     279     2896508 :             delete aData.pAsSequence;
     280     2896508 :             aData.pAsInterface = p;
     281     2896508 :             bIsList = sal_False;
     282     2896508 :             return 1;
     283             :         }
     284             :         else
     285     5552017 :             return aData.pAsSequence->getLength();
     286             :     }
     287     3560035 :     else if( aData.pAsInterface && Reference<XInterface>( aData.pAsInterface ) == rListener )
     288             :     {
     289     3551537 :         aData.pAsInterface->release();
     290     3551537 :         aData.pAsInterface = 0;
     291             :     }
     292     3560035 :     return aData.pAsInterface ? 1 : 0;
     293             : }
     294             : 
     295     2070073 : void OInterfaceContainerHelper::disposeAndClear( const EventObject & rEvt )
     296             : {
     297     2070073 :     ClearableMutexGuard aGuard( rMutex );
     298     4140146 :     OInterfaceIteratorHelper aIt( *this );
     299             :     // Release container, in case new entries come while disposing
     300             :     OSL_ENSURE( !bIsList || bInUse, "OInterfaceContainerHelper not in use" );
     301     2070073 :     if( !bIsList && aData.pAsInterface )
     302      174691 :         aData.pAsInterface->release();
     303             :     // set the member to null, use the iterator to delete the values
     304     2070073 :     aData.pAsInterface = NULL;
     305     2070073 :     bIsList = sal_False;
     306     2070073 :     bInUse = sal_False;
     307     2070073 :     aGuard.clear();
     308     4394434 :     while( aIt.hasMoreElements() )
     309             :     {
     310             :         try
     311             :         {
     312      254288 :             Reference<XEventListener > xLst( aIt.next(), UNO_QUERY );
     313      254288 :             if( xLst.is() )
     314      226164 :                 xLst->disposing( rEvt );
     315             :         }
     316        4402 :         catch ( RuntimeException & )
     317             :         {
     318             :             // be robust, if e.g. a remote bridge has disposed already.
     319             :             // there is no way to delegate the error to the caller :o(.
     320             :         }
     321     2070073 :     }
     322     2070073 : }
     323             : 
     324             : 
     325          96 : void OInterfaceContainerHelper::clear()
     326             : {
     327          96 :     ClearableMutexGuard aGuard( rMutex );
     328         192 :     OInterfaceIteratorHelper aIt( *this );
     329             :     // Release container, in case new entries come while disposing
     330             :     OSL_ENSURE( !bIsList || bInUse, "OInterfaceContainerHelper not in use" );
     331          96 :     if( !bIsList && aData.pAsInterface )
     332          18 :         aData.pAsInterface->release();
     333             :     // set the member to null, use the iterator to delete the values
     334          96 :     aData.pAsInterface = 0;
     335          96 :     bIsList = sal_False;
     336          96 :     bInUse = sal_False;
     337             :     // release mutex before aIt destructor call
     338         192 :     aGuard.clear();
     339          96 : }
     340             : 
     341             : // specialized class for type
     342             : 
     343             : typedef ::std::vector< std::pair < Type , void* > > t_type2ptr;
     344             : 
     345     2734844 : OMultiTypeInterfaceContainerHelper::OMultiTypeInterfaceContainerHelper( Mutex & rMutex_ )
     346     2734844 :     : rMutex( rMutex_ )
     347             : {
     348     2734844 :     m_pMap = new t_type2ptr();
     349     2734844 : }
     350             : 
     351     2711913 : OMultiTypeInterfaceContainerHelper::~OMultiTypeInterfaceContainerHelper()
     352             : {
     353     2711913 :     t_type2ptr * pMap = (t_type2ptr *)m_pMap;
     354     2711913 :     t_type2ptr::iterator iter = pMap->begin();
     355     2711913 :     t_type2ptr::iterator end = pMap->end();
     356             : 
     357     5680839 :     while( iter != end )
     358             :     {
     359      257013 :         delete (OInterfaceContainerHelper*)(*iter).second;
     360      257013 :         (*iter).second = 0;
     361      257013 :         ++iter;
     362             :     }
     363     2711913 :     delete pMap;
     364     2711913 : }
     365             : 
     366           0 : Sequence< Type > OMultiTypeInterfaceContainerHelper::getContainedTypes() const
     367             : {
     368           0 :     t_type2ptr * pMap = (t_type2ptr *)m_pMap;
     369             :     t_type2ptr::size_type nSize;
     370             : 
     371           0 :     ::osl::MutexGuard aGuard( rMutex );
     372           0 :     nSize = pMap->size();
     373           0 :     if( nSize )
     374             :     {
     375           0 :         ::com::sun::star::uno::Sequence< Type > aInterfaceTypes( nSize );
     376           0 :         Type * pArray = aInterfaceTypes.getArray();
     377             : 
     378           0 :         t_type2ptr::iterator iter = pMap->begin();
     379           0 :         t_type2ptr::iterator end = pMap->end();
     380             : 
     381           0 :         sal_Int32 i = 0;
     382           0 :         while( iter != end )
     383             :         {
     384             :             // are interfaces added to this container?
     385           0 :             if( ((OInterfaceContainerHelper*)(*iter).second)->getLength() )
     386             :                 // yes, put the type in the array
     387           0 :                 pArray[i++] = (*iter).first;
     388           0 :             ++iter;
     389             :         }
     390           0 :         if( (t_type2ptr::size_type)i != nSize ) {
     391             :             // may be empty container, reduce the sequence to the right size
     392           0 :             aInterfaceTypes = ::com::sun::star::uno::Sequence< Type >( pArray, i );
     393             :         }
     394           0 :         return aInterfaceTypes;
     395             :     }
     396           0 :     return ::com::sun::star::uno::Sequence< Type >();
     397             : }
     398             : 
     399     2616963 : static t_type2ptr::iterator findType(t_type2ptr *pMap, const Type & rKey )
     400             : {
     401     2616963 :     t_type2ptr::iterator iter = pMap->begin();
     402     2616964 :     t_type2ptr::iterator end = pMap->end();
     403             : 
     404     6774420 :     while( iter != end )
     405             :     {
     406     3022657 :         if (iter->first == rKey)
     407     1482165 :             break;
     408     1540492 :         ++iter;
     409             :     }
     410     2616964 :     return iter;
     411             : }
     412             : 
     413     1650295 : OInterfaceContainerHelper * OMultiTypeInterfaceContainerHelper::getContainer( const Type & rKey ) const
     414             : {
     415     1650295 :     ::osl::MutexGuard aGuard( rMutex );
     416             : 
     417     1650296 :     t_type2ptr * pMap = (t_type2ptr *)m_pMap;
     418     1650296 :      t_type2ptr::iterator iter = findType( pMap, rKey );
     419     1650297 :     if( iter != pMap->end() )
     420      776604 :             return (OInterfaceContainerHelper*) (*iter).second;
     421      873693 :     return 0;
     422             : }
     423             : 
     424      561216 : sal_Int32 OMultiTypeInterfaceContainerHelper::addInterface(
     425             :     const Type & rKey, const Reference< XInterface > & rListener )
     426             : {
     427      561216 :     ::osl::MutexGuard aGuard( rMutex );
     428      561216 :     t_type2ptr * pMap = (t_type2ptr *)m_pMap;
     429      561216 :     t_type2ptr::iterator iter = findType( pMap, rKey );
     430      561216 :     if( iter == pMap->end() )
     431             :     {
     432      261090 :         OInterfaceContainerHelper * pLC = new OInterfaceContainerHelper( rMutex );
     433      261090 :         pMap->push_back(std::pair<Type, void*>(rKey, pLC));
     434      261090 :         return pLC->addInterface( rListener );
     435             :     }
     436             :     else
     437      300126 :         return ((OInterfaceContainerHelper*)(*iter).second)->addInterface( rListener );
     438             : }
     439             : 
     440      405451 : sal_Int32 OMultiTypeInterfaceContainerHelper::removeInterface(
     441             :     const Type & rKey, const Reference< XInterface > & rListener )
     442             : {
     443      405451 :     ::osl::MutexGuard aGuard( rMutex );
     444             : 
     445             :     // search container with id nUik
     446      405451 :     t_type2ptr * pMap = (t_type2ptr *)m_pMap;
     447      405451 :     t_type2ptr::iterator iter = findType( pMap, rKey );
     448             :         // container found?
     449      405451 :     if( iter != pMap->end() )
     450      405435 :         return ((OInterfaceContainerHelper*)(*iter).second)->removeInterface( rListener );
     451             : 
     452             :     // no container with this id. Always return 0
     453          16 :     return 0;
     454             : }
     455             : 
     456     1751598 : void OMultiTypeInterfaceContainerHelper::disposeAndClear( const EventObject & rEvt )
     457             : {
     458     1751598 :     t_type2ptr::size_type nSize = 0;
     459     1751598 :     boost::scoped_array<OInterfaceContainerHelper *> ppListenerContainers;
     460             :     {
     461     1751599 :         ::osl::MutexGuard aGuard( rMutex );
     462     1751599 :         t_type2ptr * pMap = (t_type2ptr *)m_pMap;
     463     1751599 :         nSize = pMap->size();
     464     1751599 :         if( nSize )
     465             :         {
     466             :             typedef OInterfaceContainerHelper* ppp;
     467      139918 :             ppListenerContainers.reset(new ppp[nSize]);
     468             :             //ppListenerContainers = new (ListenerContainer*)[nSize];
     469             : 
     470      139918 :             t_type2ptr::iterator iter = pMap->begin();
     471      139918 :             t_type2ptr::iterator end = pMap->end();
     472             : 
     473      139918 :             t_type2ptr::size_type i = 0;
     474      497310 :             while( iter != end )
     475             :             {
     476      217474 :                 ppListenerContainers[i++] = (OInterfaceContainerHelper*)(*iter).second;
     477      217474 :                 ++iter;
     478             :             }
     479     1751599 :         }
     480             :     }
     481             : 
     482             :     // create a copy, because do not fire event in a guarded section
     483     1969073 :     for( t_type2ptr::size_type i = 0;
     484             :             i < nSize; i++ )
     485             :     {
     486      217474 :         if( ppListenerContainers[i] )
     487      217474 :             ppListenerContainers[i]->disposeAndClear( rEvt );
     488     1751599 :     }
     489     1751599 : }
     490             : 
     491           0 : void OMultiTypeInterfaceContainerHelper::clear()
     492             : {
     493           0 :     ::osl::MutexGuard aGuard( rMutex );
     494           0 :     t_type2ptr * pMap = (t_type2ptr *)m_pMap;
     495           0 :     t_type2ptr::iterator iter = pMap->begin();
     496           0 :     t_type2ptr::iterator end = pMap->end();
     497             : 
     498           0 :     while( iter != end )
     499             :     {
     500           0 :         ((OInterfaceContainerHelper*)(*iter).second)->clear();
     501           0 :         ++iter;
     502           0 :     }
     503           0 : }
     504             : 
     505             : // specialized class for long
     506             : 
     507             : typedef ::std::vector< std::pair < sal_Int32 , void* > > t_long2ptr;
     508             : 
     509       55405 : static t_long2ptr::iterator findLong(t_long2ptr *pMap, sal_Int32 nKey )
     510             : {
     511       55405 :     t_long2ptr::iterator iter = pMap->begin();
     512       55405 :     t_long2ptr::iterator end = pMap->end();
     513             : 
     514      305240 :     while( iter != end )
     515             :     {
     516      216355 :         if (iter->first == nKey)
     517       21925 :             break;
     518      194430 :         ++iter;
     519             :     }
     520       55405 :     return iter;
     521             : }
     522             : 
     523     1069596 : OMultiTypeInterfaceContainerHelperInt32::OMultiTypeInterfaceContainerHelperInt32( Mutex & rMutex_ )
     524             :     : m_pMap( NULL )
     525     1069596 :     , rMutex( rMutex_ )
     526             : {
     527             :     // delay pMap allocation until necessary.
     528     1069596 : }
     529             : 
     530     1067244 : OMultiTypeInterfaceContainerHelperInt32::~OMultiTypeInterfaceContainerHelperInt32()
     531             : {
     532     1067244 :     if (!m_pMap)
     533     1064126 :         return;
     534             : 
     535        3118 :     t_long2ptr * pMap = (t_long2ptr *)m_pMap;
     536        3118 :     t_long2ptr::iterator iter = pMap->begin();
     537        3118 :     t_long2ptr::iterator end = pMap->end();
     538             : 
     539       17314 :     while( iter != end )
     540             :     {
     541       11078 :         delete (OInterfaceContainerHelper*)(*iter).second;
     542       11078 :         (*iter).second = 0;
     543       11078 :         ++iter;
     544             :     }
     545        3118 :     delete pMap;
     546        3118 : }
     547             : 
     548           0 : Sequence< sal_Int32 > OMultiTypeInterfaceContainerHelperInt32::getContainedTypes() const
     549             : {
     550           0 :     t_long2ptr * pMap = (t_long2ptr *)m_pMap;
     551             :     t_long2ptr::size_type nSize;
     552             : 
     553           0 :     ::osl::MutexGuard aGuard( rMutex );
     554           0 :     nSize = pMap ? pMap->size() : 0;
     555           0 :     if( nSize )
     556             :     {
     557           0 :         ::com::sun::star::uno::Sequence< sal_Int32 > aInterfaceTypes( nSize );
     558           0 :         sal_Int32 * pArray = aInterfaceTypes.getArray();
     559             : 
     560           0 :         t_long2ptr::iterator iter = pMap->begin();
     561           0 :         t_long2ptr::iterator end = pMap->end();
     562             : 
     563           0 :         sal_Int32 i = 0;
     564           0 :         while( iter != end )
     565             :         {
     566             :             // are interfaces added to this container?
     567           0 :             if( ((OInterfaceContainerHelper*)(*iter).second)->getLength() )
     568             :                 // yes, put the type in the array
     569           0 :                 pArray[i++] = (*iter).first;
     570           0 :             ++iter;
     571             :         }
     572           0 :         if( (t_long2ptr::size_type)i != nSize ) {
     573             :             // may be empty container, reduce the sequence to the right size
     574           0 :             aInterfaceTypes = ::com::sun::star::uno::Sequence< sal_Int32 >( pArray, i );
     575             :         }
     576           0 :         return aInterfaceTypes;
     577             :     }
     578           0 :     return ::com::sun::star::uno::Sequence< sal_Int32 >();
     579             : }
     580             : 
     581      108423 : OInterfaceContainerHelper * OMultiTypeInterfaceContainerHelperInt32::getContainer( const sal_Int32 & rKey ) const
     582             : {
     583      108423 :     ::osl::MutexGuard aGuard( rMutex );
     584             : 
     585      108423 :     if (!m_pMap)
     586       80909 :         return 0;
     587       27514 :     t_long2ptr * pMap = (t_long2ptr *)m_pMap;
     588       27514 :      t_long2ptr::iterator iter = findLong( pMap, rKey );
     589       27514 :     if( iter != pMap->end() )
     590        5834 :             return (OInterfaceContainerHelper*) (*iter).second;
     591       21680 :     return 0;
     592             : }
     593             : 
     594       17608 : sal_Int32 OMultiTypeInterfaceContainerHelperInt32::addInterface(
     595             :     const sal_Int32 & rKey, const Reference< XInterface > & rListener )
     596             : {
     597       17608 :     ::osl::MutexGuard aGuard( rMutex );
     598       17608 :     if (!m_pMap)
     599        3336 :         m_pMap = new t_long2ptr();
     600       17608 :     t_long2ptr * pMap = (t_long2ptr *)m_pMap;
     601       17608 :     t_long2ptr::iterator iter = findLong( pMap, rKey );
     602       17608 :      if( iter == pMap->end() )
     603             :     {
     604       11726 :         OInterfaceContainerHelper * pLC = new OInterfaceContainerHelper( rMutex );
     605       11726 :         pMap->push_back(std::pair< sal_Int32, void* >(rKey, pLC));
     606       11726 :         return pLC->addInterface( rListener );
     607             :     }
     608             :     else
     609        5882 :         return ((OInterfaceContainerHelper*)(*iter).second)->addInterface( rListener );
     610             : }
     611             : 
     612       10283 : sal_Int32 OMultiTypeInterfaceContainerHelperInt32::removeInterface(
     613             :     const sal_Int32 & rKey, const Reference< XInterface > & rListener )
     614             : {
     615       10283 :     ::osl::MutexGuard aGuard( rMutex );
     616             : 
     617       10283 :     if (!m_pMap)
     618           0 :         return 0;
     619             :     // search container with id nUik
     620       10283 :     t_long2ptr * pMap = (t_long2ptr *)m_pMap;
     621       10283 :     t_long2ptr::iterator iter = findLong( pMap, rKey );
     622             :         // container found?
     623       10283 :     if( iter != pMap->end() )
     624       10209 :         return ((OInterfaceContainerHelper*)(*iter).second)->removeInterface( rListener );
     625             : 
     626             :     // no container with this id. Always return 0
     627          74 :     return 0;
     628             : }
     629             : 
     630       24948 : void OMultiTypeInterfaceContainerHelperInt32::disposeAndClear( const EventObject & rEvt )
     631             : {
     632       24948 :     t_long2ptr::size_type nSize = 0;
     633       24948 :     boost::scoped_array<OInterfaceContainerHelper *> ppListenerContainers;
     634             :     {
     635       24948 :         ::osl::MutexGuard aGuard( rMutex );
     636       24948 :         if (!m_pMap)
     637       47034 :             return;
     638             : 
     639        2862 :         t_long2ptr * pMap = (t_long2ptr *)m_pMap;
     640        2862 :         nSize = pMap->size();
     641        2862 :         if( nSize )
     642             :         {
     643             :             typedef OInterfaceContainerHelper* ppp;
     644        2862 :             ppListenerContainers.reset(new ppp[nSize]);
     645             : 
     646        2862 :             t_long2ptr::iterator iter = pMap->begin();
     647        2862 :             t_long2ptr::iterator end = pMap->end();
     648             : 
     649        2862 :             t_long2ptr::size_type i = 0;
     650       15982 :             while( iter != end )
     651             :             {
     652       10258 :                 ppListenerContainers[i++] = (OInterfaceContainerHelper*)(*iter).second;
     653       10258 :                 ++iter;
     654             :             }
     655        2862 :         }
     656             :     }
     657             : 
     658             :     // create a copy, because do not fire event in a guarded section
     659       13120 :     for( t_long2ptr::size_type i = 0;
     660             :             i < nSize; i++ )
     661             :     {
     662       10258 :         if( ppListenerContainers[i] )
     663       10258 :             ppListenerContainers[i]->disposeAndClear( rEvt );
     664        2862 :     }
     665             : }
     666             : 
     667           0 : void OMultiTypeInterfaceContainerHelperInt32::clear()
     668             : {
     669           0 :     ::osl::MutexGuard aGuard( rMutex );
     670           0 :     if (!m_pMap)
     671           0 :         return;
     672           0 :     t_long2ptr * pMap = (t_long2ptr *)m_pMap;
     673           0 :     t_long2ptr::iterator iter = pMap->begin();
     674           0 :     t_long2ptr::iterator end = pMap->end();
     675             : 
     676           0 :     while( iter != end )
     677             :     {
     678           0 :         ((OInterfaceContainerHelper*)(*iter).second)->clear();
     679           0 :         ++iter;
     680           0 :     }
     681             : }
     682             : 
     683             : }
     684             : 
     685             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10