1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_cppuhelper.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #include <cppuhelper/interfacecontainer.hxx> 32*cdf0e10cSrcweir #include <cppuhelper/queryinterface.hxx> 33*cdf0e10cSrcweir #include <cppuhelper/propshlp.hxx> 34*cdf0e10cSrcweir 35*cdf0e10cSrcweir #include <osl/diagnose.h> 36*cdf0e10cSrcweir #include <osl/mutex.hxx> 37*cdf0e10cSrcweir 38*cdf0e10cSrcweir #include <hash_map> 39*cdf0e10cSrcweir 40*cdf0e10cSrcweir #include <com/sun/star/lang/XEventListener.hpp> 41*cdf0e10cSrcweir 42*cdf0e10cSrcweir 43*cdf0e10cSrcweir using namespace osl; 44*cdf0e10cSrcweir using namespace com::sun::star::uno; 45*cdf0e10cSrcweir using namespace com::sun::star::lang; 46*cdf0e10cSrcweir 47*cdf0e10cSrcweir namespace cppu 48*cdf0e10cSrcweir { 49*cdf0e10cSrcweir 50*cdf0e10cSrcweir //=================================================================== 51*cdf0e10cSrcweir //=================================================================== 52*cdf0e10cSrcweir //=================================================================== 53*cdf0e10cSrcweir /** 54*cdf0e10cSrcweir * Reallocate the sequence. 55*cdf0e10cSrcweir */ 56*cdf0e10cSrcweir static void realloc( Sequence< Reference< XInterface > > & rSeq, sal_Int32 nNewLen ) 57*cdf0e10cSrcweir SAL_THROW( () ) 58*cdf0e10cSrcweir { 59*cdf0e10cSrcweir rSeq.realloc( nNewLen ); 60*cdf0e10cSrcweir } 61*cdf0e10cSrcweir 62*cdf0e10cSrcweir /** 63*cdf0e10cSrcweir * Remove an element from an interface sequence. 64*cdf0e10cSrcweir */ 65*cdf0e10cSrcweir static void sequenceRemoveElementAt( Sequence< Reference< XInterface > > & rSeq, sal_Int32 index ) 66*cdf0e10cSrcweir SAL_THROW( () ) 67*cdf0e10cSrcweir { 68*cdf0e10cSrcweir sal_Int32 nNewLen = rSeq.getLength() - 1; 69*cdf0e10cSrcweir 70*cdf0e10cSrcweir Sequence< Reference< XInterface > > aDestSeq( rSeq.getLength() - 1 ); 71*cdf0e10cSrcweir // getArray on a const sequence is faster 72*cdf0e10cSrcweir const Reference< XInterface > * pSource = ((const Sequence< Reference< XInterface > > &)rSeq).getConstArray(); 73*cdf0e10cSrcweir Reference< XInterface > * pDest = aDestSeq.getArray(); 74*cdf0e10cSrcweir sal_Int32 i = 0; 75*cdf0e10cSrcweir for( ; i < index; i++ ) 76*cdf0e10cSrcweir pDest[i] = pSource[i]; 77*cdf0e10cSrcweir for( sal_Int32 j = i ; j < nNewLen; j++ ) 78*cdf0e10cSrcweir pDest[j] = pSource[j+1]; 79*cdf0e10cSrcweir rSeq = aDestSeq; 80*cdf0e10cSrcweir } 81*cdf0e10cSrcweir 82*cdf0e10cSrcweir 83*cdf0e10cSrcweir //----------------------------------------------------------------------------- 84*cdf0e10cSrcweir //----------------------------------------------------------------------------- 85*cdf0e10cSrcweir 86*cdf0e10cSrcweir #ifdef _MSC_VER 87*cdf0e10cSrcweir #pragma warning( disable: 4786 ) 88*cdf0e10cSrcweir #endif 89*cdf0e10cSrcweir 90*cdf0e10cSrcweir //=================================================================== 91*cdf0e10cSrcweir //=================================================================== 92*cdf0e10cSrcweir //=================================================================== 93*cdf0e10cSrcweir OInterfaceIteratorHelper::OInterfaceIteratorHelper( OInterfaceContainerHelper & rCont_ ) 94*cdf0e10cSrcweir SAL_THROW( () ) 95*cdf0e10cSrcweir : rCont( rCont_ ) 96*cdf0e10cSrcweir { 97*cdf0e10cSrcweir MutexGuard aGuard( rCont.rMutex ); 98*cdf0e10cSrcweir if( rCont.bInUse ) 99*cdf0e10cSrcweir // worst case, two iterators at the same time 100*cdf0e10cSrcweir rCont.copyAndResetInUse(); 101*cdf0e10cSrcweir bIsList = rCont_.bIsList; 102*cdf0e10cSrcweir aData = rCont_.aData; 103*cdf0e10cSrcweir if( bIsList ) 104*cdf0e10cSrcweir { 105*cdf0e10cSrcweir rCont.bInUse = sal_True; 106*cdf0e10cSrcweir nRemain = aData.pAsSequence->getLength(); 107*cdf0e10cSrcweir } 108*cdf0e10cSrcweir else if( aData.pAsInterface ) 109*cdf0e10cSrcweir { 110*cdf0e10cSrcweir aData.pAsInterface->acquire(); 111*cdf0e10cSrcweir nRemain = 1; 112*cdf0e10cSrcweir } 113*cdf0e10cSrcweir else 114*cdf0e10cSrcweir nRemain = 0; 115*cdf0e10cSrcweir } 116*cdf0e10cSrcweir 117*cdf0e10cSrcweir OInterfaceIteratorHelper::~OInterfaceIteratorHelper() SAL_THROW( () ) 118*cdf0e10cSrcweir { 119*cdf0e10cSrcweir sal_Bool bShared; 120*cdf0e10cSrcweir { 121*cdf0e10cSrcweir MutexGuard aGuard( rCont.rMutex ); 122*cdf0e10cSrcweir // bResetInUse protect the iterator against recursion 123*cdf0e10cSrcweir bShared = aData.pAsSequence == rCont.aData.pAsSequence && rCont.bIsList; 124*cdf0e10cSrcweir if( bShared ) 125*cdf0e10cSrcweir { 126*cdf0e10cSrcweir OSL_ENSURE( rCont.bInUse, "OInterfaceContainerHelper must be in use" ); 127*cdf0e10cSrcweir rCont.bInUse = sal_False; 128*cdf0e10cSrcweir } 129*cdf0e10cSrcweir } 130*cdf0e10cSrcweir 131*cdf0e10cSrcweir if( !bShared ) 132*cdf0e10cSrcweir { 133*cdf0e10cSrcweir if( bIsList ) 134*cdf0e10cSrcweir // Sequence owned by the iterator 135*cdf0e10cSrcweir delete aData.pAsSequence; 136*cdf0e10cSrcweir else if( aData.pAsInterface ) 137*cdf0e10cSrcweir // Interface is acquired by the iterator 138*cdf0e10cSrcweir aData.pAsInterface->release(); 139*cdf0e10cSrcweir } 140*cdf0e10cSrcweir } 141*cdf0e10cSrcweir 142*cdf0e10cSrcweir XInterface * OInterfaceIteratorHelper::next() SAL_THROW( () ) 143*cdf0e10cSrcweir { 144*cdf0e10cSrcweir if( nRemain ) 145*cdf0e10cSrcweir { 146*cdf0e10cSrcweir nRemain--; 147*cdf0e10cSrcweir if( bIsList ) 148*cdf0e10cSrcweir // typecase to const,so the getArray method is faster 149*cdf0e10cSrcweir return aData.pAsSequence->getConstArray()[nRemain].get(); 150*cdf0e10cSrcweir else if( aData.pAsInterface ) 151*cdf0e10cSrcweir return aData.pAsInterface; 152*cdf0e10cSrcweir } 153*cdf0e10cSrcweir // exception 154*cdf0e10cSrcweir return 0; 155*cdf0e10cSrcweir } 156*cdf0e10cSrcweir 157*cdf0e10cSrcweir void OInterfaceIteratorHelper::remove() SAL_THROW( () ) 158*cdf0e10cSrcweir { 159*cdf0e10cSrcweir if( bIsList ) 160*cdf0e10cSrcweir { 161*cdf0e10cSrcweir OSL_ASSERT( nRemain >= 0 && 162*cdf0e10cSrcweir nRemain < aData.pAsSequence->getLength() ); 163*cdf0e10cSrcweir XInterface * p = aData.pAsSequence->getConstArray()[nRemain].get(); 164*cdf0e10cSrcweir rCont.removeInterface( * reinterpret_cast< const Reference< XInterface > * >( &p ) ); 165*cdf0e10cSrcweir } 166*cdf0e10cSrcweir else 167*cdf0e10cSrcweir { 168*cdf0e10cSrcweir OSL_ASSERT( 0 == nRemain ); 169*cdf0e10cSrcweir rCont.removeInterface( * reinterpret_cast< const Reference< XInterface > * >(&aData.pAsInterface)); 170*cdf0e10cSrcweir } 171*cdf0e10cSrcweir } 172*cdf0e10cSrcweir 173*cdf0e10cSrcweir //=================================================================== 174*cdf0e10cSrcweir //=================================================================== 175*cdf0e10cSrcweir //=================================================================== 176*cdf0e10cSrcweir 177*cdf0e10cSrcweir 178*cdf0e10cSrcweir OInterfaceContainerHelper::OInterfaceContainerHelper( Mutex & rMutex_ ) SAL_THROW( () ) 179*cdf0e10cSrcweir : rMutex( rMutex_ ) 180*cdf0e10cSrcweir , bInUse( sal_False ) 181*cdf0e10cSrcweir , bIsList( sal_False ) 182*cdf0e10cSrcweir { 183*cdf0e10cSrcweir } 184*cdf0e10cSrcweir 185*cdf0e10cSrcweir OInterfaceContainerHelper::~OInterfaceContainerHelper() SAL_THROW( () ) 186*cdf0e10cSrcweir { 187*cdf0e10cSrcweir OSL_ENSURE( !bInUse, "~OInterfaceContainerHelper but is in use" ); 188*cdf0e10cSrcweir if( bIsList ) 189*cdf0e10cSrcweir delete aData.pAsSequence; 190*cdf0e10cSrcweir else if( aData.pAsInterface ) 191*cdf0e10cSrcweir aData.pAsInterface->release(); 192*cdf0e10cSrcweir } 193*cdf0e10cSrcweir 194*cdf0e10cSrcweir sal_Int32 OInterfaceContainerHelper::getLength() const SAL_THROW( () ) 195*cdf0e10cSrcweir { 196*cdf0e10cSrcweir MutexGuard aGuard( rMutex ); 197*cdf0e10cSrcweir if( bIsList ) 198*cdf0e10cSrcweir return aData.pAsSequence->getLength(); 199*cdf0e10cSrcweir else if( aData.pAsInterface ) 200*cdf0e10cSrcweir return 1; 201*cdf0e10cSrcweir return 0; 202*cdf0e10cSrcweir } 203*cdf0e10cSrcweir 204*cdf0e10cSrcweir Sequence< Reference<XInterface> > OInterfaceContainerHelper::getElements() const SAL_THROW( () ) 205*cdf0e10cSrcweir { 206*cdf0e10cSrcweir MutexGuard aGuard( rMutex ); 207*cdf0e10cSrcweir if( bIsList ) 208*cdf0e10cSrcweir return *aData.pAsSequence; 209*cdf0e10cSrcweir else if( aData.pAsInterface ) 210*cdf0e10cSrcweir { 211*cdf0e10cSrcweir Reference<XInterface> x( aData.pAsInterface ); 212*cdf0e10cSrcweir return Sequence< Reference< XInterface > >( &x, 1 ); 213*cdf0e10cSrcweir } 214*cdf0e10cSrcweir return Sequence< Reference< XInterface > >(); 215*cdf0e10cSrcweir } 216*cdf0e10cSrcweir 217*cdf0e10cSrcweir void OInterfaceContainerHelper::copyAndResetInUse() SAL_THROW( () ) 218*cdf0e10cSrcweir { 219*cdf0e10cSrcweir OSL_ENSURE( bInUse, "OInterfaceContainerHelper not in use" ); 220*cdf0e10cSrcweir if( bInUse ) 221*cdf0e10cSrcweir { 222*cdf0e10cSrcweir // this should be the worst case. If a iterator is active 223*cdf0e10cSrcweir // and a new Listener is added. 224*cdf0e10cSrcweir if( bIsList ) 225*cdf0e10cSrcweir aData.pAsSequence = new Sequence< Reference< XInterface > >( *aData.pAsSequence ); 226*cdf0e10cSrcweir else if( aData.pAsInterface ) 227*cdf0e10cSrcweir aData.pAsInterface->acquire(); 228*cdf0e10cSrcweir 229*cdf0e10cSrcweir bInUse = sal_False; 230*cdf0e10cSrcweir } 231*cdf0e10cSrcweir } 232*cdf0e10cSrcweir 233*cdf0e10cSrcweir sal_Int32 OInterfaceContainerHelper::addInterface( const Reference<XInterface> & rListener ) SAL_THROW( () ) 234*cdf0e10cSrcweir { 235*cdf0e10cSrcweir OSL_ASSERT( rListener.is() ); 236*cdf0e10cSrcweir MutexGuard aGuard( rMutex ); 237*cdf0e10cSrcweir if( bInUse ) 238*cdf0e10cSrcweir copyAndResetInUse(); 239*cdf0e10cSrcweir 240*cdf0e10cSrcweir if( bIsList ) 241*cdf0e10cSrcweir { 242*cdf0e10cSrcweir sal_Int32 nLen = aData.pAsSequence->getLength(); 243*cdf0e10cSrcweir realloc( *aData.pAsSequence, nLen +1 ); 244*cdf0e10cSrcweir aData.pAsSequence->getArray()[ nLen ] = rListener; 245*cdf0e10cSrcweir return nLen +1; 246*cdf0e10cSrcweir } 247*cdf0e10cSrcweir else if( aData.pAsInterface ) 248*cdf0e10cSrcweir { 249*cdf0e10cSrcweir Sequence< Reference< XInterface > > * pSeq = new Sequence< Reference< XInterface > >( 2 ); 250*cdf0e10cSrcweir Reference<XInterface> * pArray = pSeq->getArray(); 251*cdf0e10cSrcweir pArray[0] = aData.pAsInterface; 252*cdf0e10cSrcweir pArray[1] = rListener; 253*cdf0e10cSrcweir aData.pAsInterface->release(); 254*cdf0e10cSrcweir aData.pAsSequence = pSeq; 255*cdf0e10cSrcweir bIsList = sal_True; 256*cdf0e10cSrcweir return 2; 257*cdf0e10cSrcweir } 258*cdf0e10cSrcweir else 259*cdf0e10cSrcweir { 260*cdf0e10cSrcweir aData.pAsInterface = rListener.get(); 261*cdf0e10cSrcweir if( rListener.is() ) 262*cdf0e10cSrcweir rListener->acquire(); 263*cdf0e10cSrcweir return 1; 264*cdf0e10cSrcweir } 265*cdf0e10cSrcweir } 266*cdf0e10cSrcweir 267*cdf0e10cSrcweir sal_Int32 OInterfaceContainerHelper::removeInterface( const Reference<XInterface> & rListener ) SAL_THROW( () ) 268*cdf0e10cSrcweir { 269*cdf0e10cSrcweir OSL_ASSERT( rListener.is() ); 270*cdf0e10cSrcweir MutexGuard aGuard( rMutex ); 271*cdf0e10cSrcweir if( bInUse ) 272*cdf0e10cSrcweir copyAndResetInUse(); 273*cdf0e10cSrcweir 274*cdf0e10cSrcweir if( bIsList ) 275*cdf0e10cSrcweir { 276*cdf0e10cSrcweir const Reference<XInterface> * pL = aData.pAsSequence->getConstArray(); 277*cdf0e10cSrcweir sal_Int32 nLen = aData.pAsSequence->getLength(); 278*cdf0e10cSrcweir sal_Int32 i; 279*cdf0e10cSrcweir for( i = 0; i < nLen; i++ ) 280*cdf0e10cSrcweir { 281*cdf0e10cSrcweir // It is not valid to compare the Pointer direkt, but is is is much 282*cdf0e10cSrcweir // more faster. 283*cdf0e10cSrcweir if( pL[i].get() == rListener.get() ) 284*cdf0e10cSrcweir { 285*cdf0e10cSrcweir sequenceRemoveElementAt( *aData.pAsSequence, i ); 286*cdf0e10cSrcweir break; 287*cdf0e10cSrcweir } 288*cdf0e10cSrcweir } 289*cdf0e10cSrcweir 290*cdf0e10cSrcweir if( i == nLen ) 291*cdf0e10cSrcweir { 292*cdf0e10cSrcweir // interface not found, use the correct compare method 293*cdf0e10cSrcweir for( i = 0; i < nLen; i++ ) 294*cdf0e10cSrcweir { 295*cdf0e10cSrcweir if( pL[i] == rListener ) 296*cdf0e10cSrcweir { 297*cdf0e10cSrcweir sequenceRemoveElementAt(*aData.pAsSequence, i ); 298*cdf0e10cSrcweir break; 299*cdf0e10cSrcweir } 300*cdf0e10cSrcweir } 301*cdf0e10cSrcweir } 302*cdf0e10cSrcweir 303*cdf0e10cSrcweir if( aData.pAsSequence->getLength() == 1 ) 304*cdf0e10cSrcweir { 305*cdf0e10cSrcweir XInterface * p = aData.pAsSequence->getConstArray()[0].get(); 306*cdf0e10cSrcweir p->acquire(); 307*cdf0e10cSrcweir delete aData.pAsSequence; 308*cdf0e10cSrcweir aData.pAsInterface = p; 309*cdf0e10cSrcweir bIsList = sal_False; 310*cdf0e10cSrcweir return 1; 311*cdf0e10cSrcweir } 312*cdf0e10cSrcweir else 313*cdf0e10cSrcweir return aData.pAsSequence->getLength(); 314*cdf0e10cSrcweir } 315*cdf0e10cSrcweir else if( aData.pAsInterface && Reference<XInterface>( aData.pAsInterface ) == rListener ) 316*cdf0e10cSrcweir { 317*cdf0e10cSrcweir aData.pAsInterface->release(); 318*cdf0e10cSrcweir aData.pAsInterface = 0; 319*cdf0e10cSrcweir } 320*cdf0e10cSrcweir return aData.pAsInterface ? 1 : 0; 321*cdf0e10cSrcweir } 322*cdf0e10cSrcweir 323*cdf0e10cSrcweir void OInterfaceContainerHelper::disposeAndClear( const EventObject & rEvt ) SAL_THROW( () ) 324*cdf0e10cSrcweir { 325*cdf0e10cSrcweir ClearableMutexGuard aGuard( rMutex ); 326*cdf0e10cSrcweir OInterfaceIteratorHelper aIt( *this ); 327*cdf0e10cSrcweir // Container freigeben, falls im disposing neue Eintr�ge kommen 328*cdf0e10cSrcweir OSL_ENSURE( !bIsList || bInUse, "OInterfaceContainerHelper not in use" ); 329*cdf0e10cSrcweir if( !bIsList && aData.pAsInterface ) 330*cdf0e10cSrcweir aData.pAsInterface->release(); 331*cdf0e10cSrcweir // set the member to null, the iterator delete the values 332*cdf0e10cSrcweir aData.pAsInterface = NULL; 333*cdf0e10cSrcweir bIsList = sal_False; 334*cdf0e10cSrcweir bInUse = sal_False; 335*cdf0e10cSrcweir aGuard.clear(); 336*cdf0e10cSrcweir while( aIt.hasMoreElements() ) 337*cdf0e10cSrcweir { 338*cdf0e10cSrcweir try 339*cdf0e10cSrcweir { 340*cdf0e10cSrcweir Reference<XEventListener > xLst( aIt.next(), UNO_QUERY ); 341*cdf0e10cSrcweir if( xLst.is() ) 342*cdf0e10cSrcweir xLst->disposing( rEvt ); 343*cdf0e10cSrcweir } 344*cdf0e10cSrcweir catch ( RuntimeException & ) 345*cdf0e10cSrcweir { 346*cdf0e10cSrcweir // be robust, if e.g. a remote bridge has disposed already. 347*cdf0e10cSrcweir // there is no way, to delegate the error to the caller :o(. 348*cdf0e10cSrcweir } 349*cdf0e10cSrcweir } 350*cdf0e10cSrcweir } 351*cdf0e10cSrcweir 352*cdf0e10cSrcweir 353*cdf0e10cSrcweir void OInterfaceContainerHelper::clear() SAL_THROW( () ) 354*cdf0e10cSrcweir { 355*cdf0e10cSrcweir ClearableMutexGuard aGuard( rMutex ); 356*cdf0e10cSrcweir OInterfaceIteratorHelper aIt( *this ); 357*cdf0e10cSrcweir // Container freigeben, falls im disposing neue Eintr�ge kommen 358*cdf0e10cSrcweir OSL_ENSURE( !bIsList || bInUse, "OInterfaceContainerHelper not in use" ); 359*cdf0e10cSrcweir if( !bIsList && aData.pAsInterface ) 360*cdf0e10cSrcweir aData.pAsInterface->release(); 361*cdf0e10cSrcweir // set the member to null, the iterator delete the values 362*cdf0e10cSrcweir aData.pAsInterface = 0; 363*cdf0e10cSrcweir bIsList = sal_False; 364*cdf0e10cSrcweir bInUse = sal_False; 365*cdf0e10cSrcweir // release mutex before aIt destructor call 366*cdf0e10cSrcweir aGuard.clear(); 367*cdf0e10cSrcweir } 368*cdf0e10cSrcweir 369*cdf0e10cSrcweir //################################################################################################## 370*cdf0e10cSrcweir //################################################################################################## 371*cdf0e10cSrcweir //################################################################################################## 372*cdf0e10cSrcweir 373*cdf0e10cSrcweir // specialized class for type 374*cdf0e10cSrcweir 375*cdf0e10cSrcweir typedef ::std::vector< std::pair < Type , void* > > t_type2ptr; 376*cdf0e10cSrcweir 377*cdf0e10cSrcweir OMultiTypeInterfaceContainerHelper::OMultiTypeInterfaceContainerHelper( Mutex & rMutex_ ) 378*cdf0e10cSrcweir SAL_THROW( () ) 379*cdf0e10cSrcweir : rMutex( rMutex_ ) 380*cdf0e10cSrcweir { 381*cdf0e10cSrcweir m_pMap = new t_type2ptr(); 382*cdf0e10cSrcweir } 383*cdf0e10cSrcweir OMultiTypeInterfaceContainerHelper::~OMultiTypeInterfaceContainerHelper() 384*cdf0e10cSrcweir SAL_THROW( () ) 385*cdf0e10cSrcweir { 386*cdf0e10cSrcweir t_type2ptr * pMap = (t_type2ptr *)m_pMap; 387*cdf0e10cSrcweir t_type2ptr::iterator iter = pMap->begin(); 388*cdf0e10cSrcweir t_type2ptr::iterator end = pMap->end(); 389*cdf0e10cSrcweir 390*cdf0e10cSrcweir while( iter != end ) 391*cdf0e10cSrcweir { 392*cdf0e10cSrcweir delete (OInterfaceContainerHelper*)(*iter).second; 393*cdf0e10cSrcweir (*iter).second = 0; 394*cdf0e10cSrcweir ++iter; 395*cdf0e10cSrcweir } 396*cdf0e10cSrcweir delete pMap; 397*cdf0e10cSrcweir } 398*cdf0e10cSrcweir Sequence< Type > OMultiTypeInterfaceContainerHelper::getContainedTypes() const 399*cdf0e10cSrcweir SAL_THROW( () ) 400*cdf0e10cSrcweir { 401*cdf0e10cSrcweir t_type2ptr * pMap = (t_type2ptr *)m_pMap; 402*cdf0e10cSrcweir t_type2ptr::size_type nSize; 403*cdf0e10cSrcweir 404*cdf0e10cSrcweir ::osl::MutexGuard aGuard( rMutex ); 405*cdf0e10cSrcweir nSize = pMap->size(); 406*cdf0e10cSrcweir if( nSize ) 407*cdf0e10cSrcweir { 408*cdf0e10cSrcweir ::com::sun::star::uno::Sequence< Type > aInterfaceTypes( nSize ); 409*cdf0e10cSrcweir Type * pArray = aInterfaceTypes.getArray(); 410*cdf0e10cSrcweir 411*cdf0e10cSrcweir t_type2ptr::iterator iter = pMap->begin(); 412*cdf0e10cSrcweir t_type2ptr::iterator end = pMap->end(); 413*cdf0e10cSrcweir 414*cdf0e10cSrcweir sal_Int32 i = 0; 415*cdf0e10cSrcweir while( iter != end ) 416*cdf0e10cSrcweir { 417*cdf0e10cSrcweir // are interfaces added to this container? 418*cdf0e10cSrcweir if( ((OInterfaceContainerHelper*)(*iter).second)->getLength() ) 419*cdf0e10cSrcweir // yes, put the type in the array 420*cdf0e10cSrcweir pArray[i++] = (*iter).first; 421*cdf0e10cSrcweir ++iter; 422*cdf0e10cSrcweir } 423*cdf0e10cSrcweir if( (t_type2ptr::size_type)i != nSize ) { 424*cdf0e10cSrcweir // may be empty container, reduce the sequence to the right size 425*cdf0e10cSrcweir aInterfaceTypes = ::com::sun::star::uno::Sequence< Type >( pArray, i ); 426*cdf0e10cSrcweir } 427*cdf0e10cSrcweir return aInterfaceTypes; 428*cdf0e10cSrcweir } 429*cdf0e10cSrcweir return ::com::sun::star::uno::Sequence< Type >(); 430*cdf0e10cSrcweir } 431*cdf0e10cSrcweir 432*cdf0e10cSrcweir static t_type2ptr::iterator findType(t_type2ptr *pMap, const Type & rKey ) 433*cdf0e10cSrcweir { 434*cdf0e10cSrcweir t_type2ptr::iterator iter = pMap->begin(); 435*cdf0e10cSrcweir t_type2ptr::iterator end = pMap->end(); 436*cdf0e10cSrcweir 437*cdf0e10cSrcweir while( iter != end ) 438*cdf0e10cSrcweir { 439*cdf0e10cSrcweir if (iter->first == rKey) 440*cdf0e10cSrcweir break; 441*cdf0e10cSrcweir iter++; 442*cdf0e10cSrcweir } 443*cdf0e10cSrcweir return iter; 444*cdf0e10cSrcweir } 445*cdf0e10cSrcweir 446*cdf0e10cSrcweir OInterfaceContainerHelper * OMultiTypeInterfaceContainerHelper::getContainer( const Type & rKey ) const 447*cdf0e10cSrcweir SAL_THROW( () ) 448*cdf0e10cSrcweir { 449*cdf0e10cSrcweir ::osl::MutexGuard aGuard( rMutex ); 450*cdf0e10cSrcweir 451*cdf0e10cSrcweir t_type2ptr * pMap = (t_type2ptr *)m_pMap; 452*cdf0e10cSrcweir t_type2ptr::iterator iter = findType( pMap, rKey ); 453*cdf0e10cSrcweir if( iter != pMap->end() ) 454*cdf0e10cSrcweir return (OInterfaceContainerHelper*) (*iter).second; 455*cdf0e10cSrcweir return 0; 456*cdf0e10cSrcweir } 457*cdf0e10cSrcweir sal_Int32 OMultiTypeInterfaceContainerHelper::addInterface( 458*cdf0e10cSrcweir const Type & rKey, const Reference< XInterface > & rListener ) 459*cdf0e10cSrcweir SAL_THROW( () ) 460*cdf0e10cSrcweir { 461*cdf0e10cSrcweir ::osl::MutexGuard aGuard( rMutex ); 462*cdf0e10cSrcweir t_type2ptr * pMap = (t_type2ptr *)m_pMap; 463*cdf0e10cSrcweir t_type2ptr::iterator iter = findType( pMap, rKey ); 464*cdf0e10cSrcweir if( iter == pMap->end() ) 465*cdf0e10cSrcweir { 466*cdf0e10cSrcweir OInterfaceContainerHelper * pLC = new OInterfaceContainerHelper( rMutex ); 467*cdf0e10cSrcweir pMap->push_back(std::pair<Type, void*>(rKey, pLC)); 468*cdf0e10cSrcweir return pLC->addInterface( rListener ); 469*cdf0e10cSrcweir } 470*cdf0e10cSrcweir else 471*cdf0e10cSrcweir return ((OInterfaceContainerHelper*)(*iter).second)->addInterface( rListener ); 472*cdf0e10cSrcweir } 473*cdf0e10cSrcweir sal_Int32 OMultiTypeInterfaceContainerHelper::removeInterface( 474*cdf0e10cSrcweir const Type & rKey, const Reference< XInterface > & rListener ) 475*cdf0e10cSrcweir SAL_THROW( () ) 476*cdf0e10cSrcweir { 477*cdf0e10cSrcweir ::osl::MutexGuard aGuard( rMutex ); 478*cdf0e10cSrcweir 479*cdf0e10cSrcweir // search container with id nUik 480*cdf0e10cSrcweir t_type2ptr * pMap = (t_type2ptr *)m_pMap; 481*cdf0e10cSrcweir t_type2ptr::iterator iter = findType( pMap, rKey ); 482*cdf0e10cSrcweir // container found? 483*cdf0e10cSrcweir if( iter != pMap->end() ) 484*cdf0e10cSrcweir return ((OInterfaceContainerHelper*)(*iter).second)->removeInterface( rListener ); 485*cdf0e10cSrcweir 486*cdf0e10cSrcweir // no container with this id. Always return 0 487*cdf0e10cSrcweir return 0; 488*cdf0e10cSrcweir } 489*cdf0e10cSrcweir void OMultiTypeInterfaceContainerHelper::disposeAndClear( const EventObject & rEvt ) 490*cdf0e10cSrcweir SAL_THROW( () ) 491*cdf0e10cSrcweir { 492*cdf0e10cSrcweir t_type2ptr::size_type nSize = 0; 493*cdf0e10cSrcweir OInterfaceContainerHelper ** ppListenerContainers = NULL; 494*cdf0e10cSrcweir { 495*cdf0e10cSrcweir ::osl::MutexGuard aGuard( rMutex ); 496*cdf0e10cSrcweir t_type2ptr * pMap = (t_type2ptr *)m_pMap; 497*cdf0e10cSrcweir nSize = pMap->size(); 498*cdf0e10cSrcweir if( nSize ) 499*cdf0e10cSrcweir { 500*cdf0e10cSrcweir typedef OInterfaceContainerHelper* ppp; 501*cdf0e10cSrcweir ppListenerContainers = new ppp[nSize]; 502*cdf0e10cSrcweir //ppListenerContainers = new (ListenerContainer*)[nSize]; 503*cdf0e10cSrcweir 504*cdf0e10cSrcweir t_type2ptr::iterator iter = pMap->begin(); 505*cdf0e10cSrcweir t_type2ptr::iterator end = pMap->end(); 506*cdf0e10cSrcweir 507*cdf0e10cSrcweir t_type2ptr::size_type i = 0; 508*cdf0e10cSrcweir while( iter != end ) 509*cdf0e10cSrcweir { 510*cdf0e10cSrcweir ppListenerContainers[i++] = (OInterfaceContainerHelper*)(*iter).second; 511*cdf0e10cSrcweir ++iter; 512*cdf0e10cSrcweir } 513*cdf0e10cSrcweir } 514*cdf0e10cSrcweir } 515*cdf0e10cSrcweir 516*cdf0e10cSrcweir // create a copy, because do not fire event in a guarded section 517*cdf0e10cSrcweir for( t_type2ptr::size_type i = 0; 518*cdf0e10cSrcweir i < nSize; i++ ) 519*cdf0e10cSrcweir { 520*cdf0e10cSrcweir if( ppListenerContainers[i] ) 521*cdf0e10cSrcweir ppListenerContainers[i]->disposeAndClear( rEvt ); 522*cdf0e10cSrcweir } 523*cdf0e10cSrcweir 524*cdf0e10cSrcweir delete [] ppListenerContainers; 525*cdf0e10cSrcweir } 526*cdf0e10cSrcweir void OMultiTypeInterfaceContainerHelper::clear() 527*cdf0e10cSrcweir SAL_THROW( () ) 528*cdf0e10cSrcweir { 529*cdf0e10cSrcweir ::osl::MutexGuard aGuard( rMutex ); 530*cdf0e10cSrcweir t_type2ptr * pMap = (t_type2ptr *)m_pMap; 531*cdf0e10cSrcweir t_type2ptr::iterator iter = pMap->begin(); 532*cdf0e10cSrcweir t_type2ptr::iterator end = pMap->end(); 533*cdf0e10cSrcweir 534*cdf0e10cSrcweir while( iter != end ) 535*cdf0e10cSrcweir { 536*cdf0e10cSrcweir ((OInterfaceContainerHelper*)(*iter).second)->clear(); 537*cdf0e10cSrcweir ++iter; 538*cdf0e10cSrcweir } 539*cdf0e10cSrcweir } 540*cdf0e10cSrcweir 541*cdf0e10cSrcweir 542*cdf0e10cSrcweir //################################################################################################## 543*cdf0e10cSrcweir //################################################################################################## 544*cdf0e10cSrcweir //################################################################################################## 545*cdf0e10cSrcweir 546*cdf0e10cSrcweir // specialized class for long 547*cdf0e10cSrcweir 548*cdf0e10cSrcweir typedef ::std::vector< std::pair < sal_Int32 , void* > > t_long2ptr; 549*cdf0e10cSrcweir 550*cdf0e10cSrcweir static t_long2ptr::iterator findLong(t_long2ptr *pMap, sal_Int32 nKey ) 551*cdf0e10cSrcweir { 552*cdf0e10cSrcweir t_long2ptr::iterator iter = pMap->begin(); 553*cdf0e10cSrcweir t_long2ptr::iterator end = pMap->end(); 554*cdf0e10cSrcweir 555*cdf0e10cSrcweir while( iter != end ) 556*cdf0e10cSrcweir { 557*cdf0e10cSrcweir if (iter->first == nKey) 558*cdf0e10cSrcweir break; 559*cdf0e10cSrcweir iter++; 560*cdf0e10cSrcweir } 561*cdf0e10cSrcweir return iter; 562*cdf0e10cSrcweir } 563*cdf0e10cSrcweir 564*cdf0e10cSrcweir OMultiTypeInterfaceContainerHelperInt32::OMultiTypeInterfaceContainerHelperInt32( Mutex & rMutex_ ) 565*cdf0e10cSrcweir SAL_THROW( () ) 566*cdf0e10cSrcweir : m_pMap( NULL ) 567*cdf0e10cSrcweir , rMutex( rMutex_ ) 568*cdf0e10cSrcweir { 569*cdf0e10cSrcweir // delay pMap allocation until necessary. 570*cdf0e10cSrcweir } 571*cdf0e10cSrcweir OMultiTypeInterfaceContainerHelperInt32::~OMultiTypeInterfaceContainerHelperInt32() 572*cdf0e10cSrcweir SAL_THROW( () ) 573*cdf0e10cSrcweir { 574*cdf0e10cSrcweir if (!m_pMap) 575*cdf0e10cSrcweir return; 576*cdf0e10cSrcweir 577*cdf0e10cSrcweir t_long2ptr * pMap = (t_long2ptr *)m_pMap; 578*cdf0e10cSrcweir t_long2ptr::iterator iter = pMap->begin(); 579*cdf0e10cSrcweir t_long2ptr::iterator end = pMap->end(); 580*cdf0e10cSrcweir 581*cdf0e10cSrcweir while( iter != end ) 582*cdf0e10cSrcweir { 583*cdf0e10cSrcweir delete (OInterfaceContainerHelper*)(*iter).second; 584*cdf0e10cSrcweir (*iter).second = 0; 585*cdf0e10cSrcweir ++iter; 586*cdf0e10cSrcweir } 587*cdf0e10cSrcweir delete pMap; 588*cdf0e10cSrcweir } 589*cdf0e10cSrcweir Sequence< sal_Int32 > OMultiTypeInterfaceContainerHelperInt32::getContainedTypes() const 590*cdf0e10cSrcweir SAL_THROW( () ) 591*cdf0e10cSrcweir { 592*cdf0e10cSrcweir t_long2ptr * pMap = (t_long2ptr *)m_pMap; 593*cdf0e10cSrcweir t_long2ptr::size_type nSize; 594*cdf0e10cSrcweir 595*cdf0e10cSrcweir ::osl::MutexGuard aGuard( rMutex ); 596*cdf0e10cSrcweir nSize = pMap ? pMap->size() : 0; 597*cdf0e10cSrcweir if( nSize ) 598*cdf0e10cSrcweir { 599*cdf0e10cSrcweir ::com::sun::star::uno::Sequence< sal_Int32 > aInterfaceTypes( nSize ); 600*cdf0e10cSrcweir sal_Int32 * pArray = aInterfaceTypes.getArray(); 601*cdf0e10cSrcweir 602*cdf0e10cSrcweir t_long2ptr::iterator iter = pMap->begin(); 603*cdf0e10cSrcweir t_long2ptr::iterator end = pMap->end(); 604*cdf0e10cSrcweir 605*cdf0e10cSrcweir sal_Int32 i = 0; 606*cdf0e10cSrcweir while( iter != end ) 607*cdf0e10cSrcweir { 608*cdf0e10cSrcweir // are interfaces added to this container? 609*cdf0e10cSrcweir if( ((OInterfaceContainerHelper*)(*iter).second)->getLength() ) 610*cdf0e10cSrcweir // yes, put the type in the array 611*cdf0e10cSrcweir pArray[i++] = (*iter).first; 612*cdf0e10cSrcweir ++iter; 613*cdf0e10cSrcweir } 614*cdf0e10cSrcweir if( (t_long2ptr::size_type)i != nSize ) { 615*cdf0e10cSrcweir // may be empty container, reduce the sequence to the right size 616*cdf0e10cSrcweir aInterfaceTypes = ::com::sun::star::uno::Sequence< sal_Int32 >( pArray, i ); 617*cdf0e10cSrcweir } 618*cdf0e10cSrcweir return aInterfaceTypes; 619*cdf0e10cSrcweir } 620*cdf0e10cSrcweir return ::com::sun::star::uno::Sequence< sal_Int32 >(); 621*cdf0e10cSrcweir } 622*cdf0e10cSrcweir OInterfaceContainerHelper * OMultiTypeInterfaceContainerHelperInt32::getContainer( const sal_Int32 & rKey ) const 623*cdf0e10cSrcweir SAL_THROW( () ) 624*cdf0e10cSrcweir { 625*cdf0e10cSrcweir ::osl::MutexGuard aGuard( rMutex ); 626*cdf0e10cSrcweir 627*cdf0e10cSrcweir if (!m_pMap) 628*cdf0e10cSrcweir return 0; 629*cdf0e10cSrcweir t_long2ptr * pMap = (t_long2ptr *)m_pMap; 630*cdf0e10cSrcweir t_long2ptr::iterator iter = findLong( pMap, rKey ); 631*cdf0e10cSrcweir if( iter != pMap->end() ) 632*cdf0e10cSrcweir return (OInterfaceContainerHelper*) (*iter).second; 633*cdf0e10cSrcweir return 0; 634*cdf0e10cSrcweir } 635*cdf0e10cSrcweir sal_Int32 OMultiTypeInterfaceContainerHelperInt32::addInterface( 636*cdf0e10cSrcweir const sal_Int32 & rKey, const Reference< XInterface > & rListener ) 637*cdf0e10cSrcweir SAL_THROW( () ) 638*cdf0e10cSrcweir { 639*cdf0e10cSrcweir ::osl::MutexGuard aGuard( rMutex ); 640*cdf0e10cSrcweir if (!m_pMap) 641*cdf0e10cSrcweir m_pMap = new t_long2ptr(); 642*cdf0e10cSrcweir t_long2ptr * pMap = (t_long2ptr *)m_pMap; 643*cdf0e10cSrcweir t_long2ptr::iterator iter = findLong( pMap, rKey ); 644*cdf0e10cSrcweir if( iter == pMap->end() ) 645*cdf0e10cSrcweir { 646*cdf0e10cSrcweir OInterfaceContainerHelper * pLC = new OInterfaceContainerHelper( rMutex ); 647*cdf0e10cSrcweir pMap->push_back(std::pair< sal_Int32, void* >(rKey, pLC)); 648*cdf0e10cSrcweir return pLC->addInterface( rListener ); 649*cdf0e10cSrcweir } 650*cdf0e10cSrcweir else 651*cdf0e10cSrcweir return ((OInterfaceContainerHelper*)(*iter).second)->addInterface( rListener ); 652*cdf0e10cSrcweir } 653*cdf0e10cSrcweir sal_Int32 OMultiTypeInterfaceContainerHelperInt32::removeInterface( 654*cdf0e10cSrcweir const sal_Int32 & rKey, const Reference< XInterface > & rListener ) 655*cdf0e10cSrcweir SAL_THROW( () ) 656*cdf0e10cSrcweir { 657*cdf0e10cSrcweir ::osl::MutexGuard aGuard( rMutex ); 658*cdf0e10cSrcweir 659*cdf0e10cSrcweir if (!m_pMap) 660*cdf0e10cSrcweir return 0; 661*cdf0e10cSrcweir // search container with id nUik 662*cdf0e10cSrcweir t_long2ptr * pMap = (t_long2ptr *)m_pMap; 663*cdf0e10cSrcweir t_long2ptr::iterator iter = findLong( pMap, rKey ); 664*cdf0e10cSrcweir // container found? 665*cdf0e10cSrcweir if( iter != pMap->end() ) 666*cdf0e10cSrcweir return ((OInterfaceContainerHelper*)(*iter).second)->removeInterface( rListener ); 667*cdf0e10cSrcweir 668*cdf0e10cSrcweir // no container with this id. Always return 0 669*cdf0e10cSrcweir return 0; 670*cdf0e10cSrcweir } 671*cdf0e10cSrcweir void OMultiTypeInterfaceContainerHelperInt32::disposeAndClear( const EventObject & rEvt ) 672*cdf0e10cSrcweir SAL_THROW( () ) 673*cdf0e10cSrcweir { 674*cdf0e10cSrcweir t_long2ptr::size_type nSize = 0; 675*cdf0e10cSrcweir OInterfaceContainerHelper ** ppListenerContainers = NULL; 676*cdf0e10cSrcweir { 677*cdf0e10cSrcweir ::osl::MutexGuard aGuard( rMutex ); 678*cdf0e10cSrcweir if (!m_pMap) 679*cdf0e10cSrcweir return; 680*cdf0e10cSrcweir 681*cdf0e10cSrcweir t_long2ptr * pMap = (t_long2ptr *)m_pMap; 682*cdf0e10cSrcweir nSize = pMap->size(); 683*cdf0e10cSrcweir if( nSize ) 684*cdf0e10cSrcweir { 685*cdf0e10cSrcweir typedef OInterfaceContainerHelper* ppp; 686*cdf0e10cSrcweir ppListenerContainers = new ppp[nSize]; 687*cdf0e10cSrcweir //ppListenerContainers = new (ListenerContainer*)[nSize]; 688*cdf0e10cSrcweir 689*cdf0e10cSrcweir t_long2ptr::iterator iter = pMap->begin(); 690*cdf0e10cSrcweir t_long2ptr::iterator end = pMap->end(); 691*cdf0e10cSrcweir 692*cdf0e10cSrcweir t_long2ptr::size_type i = 0; 693*cdf0e10cSrcweir while( iter != end ) 694*cdf0e10cSrcweir { 695*cdf0e10cSrcweir ppListenerContainers[i++] = (OInterfaceContainerHelper*)(*iter).second; 696*cdf0e10cSrcweir ++iter; 697*cdf0e10cSrcweir } 698*cdf0e10cSrcweir } 699*cdf0e10cSrcweir } 700*cdf0e10cSrcweir 701*cdf0e10cSrcweir // create a copy, because do not fire event in a guarded section 702*cdf0e10cSrcweir for( t_long2ptr::size_type i = 0; 703*cdf0e10cSrcweir i < nSize; i++ ) 704*cdf0e10cSrcweir { 705*cdf0e10cSrcweir if( ppListenerContainers[i] ) 706*cdf0e10cSrcweir ppListenerContainers[i]->disposeAndClear( rEvt ); 707*cdf0e10cSrcweir } 708*cdf0e10cSrcweir 709*cdf0e10cSrcweir delete [] ppListenerContainers; 710*cdf0e10cSrcweir } 711*cdf0e10cSrcweir void OMultiTypeInterfaceContainerHelperInt32::clear() 712*cdf0e10cSrcweir SAL_THROW( () ) 713*cdf0e10cSrcweir { 714*cdf0e10cSrcweir ::osl::MutexGuard aGuard( rMutex ); 715*cdf0e10cSrcweir if (!m_pMap) 716*cdf0e10cSrcweir return; 717*cdf0e10cSrcweir t_long2ptr * pMap = (t_long2ptr *)m_pMap; 718*cdf0e10cSrcweir t_long2ptr::iterator iter = pMap->begin(); 719*cdf0e10cSrcweir t_long2ptr::iterator end = pMap->end(); 720*cdf0e10cSrcweir 721*cdf0e10cSrcweir while( iter != end ) 722*cdf0e10cSrcweir { 723*cdf0e10cSrcweir ((OInterfaceContainerHelper*)(*iter).second)->clear(); 724*cdf0e10cSrcweir ++iter; 725*cdf0e10cSrcweir } 726*cdf0e10cSrcweir } 727*cdf0e10cSrcweir 728*cdf0e10cSrcweir } 729*cdf0e10cSrcweir 730