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