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