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