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