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 55436 : static void realloc( Sequence< Reference< XInterface > > & rSeq, sal_Int32 nNewLen )
43 : SAL_THROW(())
44 : {
45 55436 : rSeq.realloc( nNewLen );
46 55436 : }
47 :
48 : /**
49 : * Remove an element from an interface sequence.
50 : */
51 80261 : static void sequenceRemoveElementAt( Sequence< Reference< XInterface > > & rSeq, sal_Int32 index )
52 : SAL_THROW(())
53 : {
54 80261 : sal_Int32 nNewLen = rSeq.getLength() - 1;
55 :
56 80261 : Sequence< Reference< XInterface > > aDestSeq( rSeq.getLength() - 1 );
57 : // getArray on a const sequence is faster
58 80261 : const Reference< XInterface > * pSource = ((const Sequence< Reference< XInterface > > &)rSeq).getConstArray();
59 80261 : Reference< XInterface > * pDest = aDestSeq.getArray();
60 80261 : sal_Int32 i = 0;
61 184575 : for( ; i < index; i++ )
62 104314 : pDest[i] = pSource[i];
63 154864 : for( sal_Int32 j = i ; j < nNewLen; j++ )
64 74603 : pDest[j] = pSource[j+1];
65 80261 : rSeq = aDestSeq;
66 80261 : }
67 :
68 : #ifdef _MSC_VER
69 : #pragma warning( disable: 4786 )
70 : #endif
71 :
72 93157 : OInterfaceIteratorHelper::OInterfaceIteratorHelper( OInterfaceContainerHelper & rCont_ )
73 : SAL_THROW(())
74 93157 : : rCont( rCont_ )
75 : {
76 93157 : MutexGuard aGuard( rCont.rMutex );
77 93157 : if( rCont.bInUse )
78 : // worst case, two iterators at the same time
79 1 : rCont.copyAndResetInUse();
80 93157 : bIsList = rCont_.bIsList;
81 93157 : aData = rCont_.aData;
82 93157 : if( bIsList )
83 : {
84 7461 : rCont.bInUse = sal_True;
85 7461 : nRemain = aData.pAsSequence->getLength();
86 : }
87 85696 : else if( aData.pAsInterface )
88 : {
89 54009 : aData.pAsInterface->acquire();
90 54009 : nRemain = 1;
91 : }
92 : else
93 31687 : nRemain = 0;
94 93157 : }
95 :
96 93157 : OInterfaceIteratorHelper::~OInterfaceIteratorHelper() SAL_THROW(())
97 : {
98 : sal_Bool bShared;
99 : {
100 93157 : MutexGuard aGuard( rCont.rMutex );
101 : // bResetInUse protect the iterator against recursion
102 93157 : bShared = aData.pAsSequence == rCont.aData.pAsSequence && rCont.bIsList;
103 93157 : if( bShared )
104 : {
105 : OSL_ENSURE( rCont.bInUse, "OInterfaceContainerHelper must be in use" );
106 5807 : rCont.bInUse = sal_False;
107 93157 : }
108 : }
109 :
110 93157 : if( !bShared )
111 : {
112 87350 : if( bIsList )
113 : // Sequence owned by the iterator
114 1654 : delete aData.pAsSequence;
115 85696 : else if( aData.pAsInterface )
116 : // Interface is acquired by the iterator
117 54009 : aData.pAsInterface->release();
118 : }
119 93157 : }
120 :
121 74046 : XInterface * OInterfaceIteratorHelper::next() SAL_THROW(())
122 : {
123 74046 : if( nRemain )
124 : {
125 74046 : nRemain--;
126 74046 : if( bIsList )
127 : // typecase to const,so the getArray method is faster
128 20037 : return aData.pAsSequence->getConstArray()[nRemain].get();
129 54009 : else if( aData.pAsInterface )
130 54009 : return aData.pAsInterface;
131 : }
132 : // exception
133 0 : return 0;
134 : }
135 :
136 0 : void OInterfaceIteratorHelper::remove() SAL_THROW(())
137 : {
138 0 : if( bIsList )
139 : {
140 : OSL_ASSERT( nRemain >= 0 &&
141 : nRemain < aData.pAsSequence->getLength() );
142 0 : XInterface * p = aData.pAsSequence->getConstArray()[nRemain].get();
143 0 : rCont.removeInterface( * reinterpret_cast< const Reference< XInterface > * >( &p ) );
144 : }
145 : else
146 : {
147 : OSL_ASSERT( 0 == nRemain );
148 0 : rCont.removeInterface( * reinterpret_cast< const Reference< XInterface > * >(&aData.pAsInterface));
149 : }
150 0 : }
151 :
152 111244 : OInterfaceContainerHelper::OInterfaceContainerHelper( Mutex & rMutex_ ) SAL_THROW(())
153 : : rMutex( rMutex_ )
154 : , bInUse( sal_False )
155 111244 : , bIsList( sal_False )
156 : {
157 111244 : }
158 :
159 72647 : OInterfaceContainerHelper::~OInterfaceContainerHelper() SAL_THROW(())
160 : {
161 : OSL_ENSURE( !bInUse, "~OInterfaceContainerHelper but is in use" );
162 72647 : if( bIsList )
163 0 : delete aData.pAsSequence;
164 72647 : else if( aData.pAsInterface )
165 563 : aData.pAsInterface->release();
166 72647 : }
167 :
168 14448 : sal_Int32 OInterfaceContainerHelper::getLength() const SAL_THROW(())
169 : {
170 14448 : MutexGuard aGuard( rMutex );
171 14448 : if( bIsList )
172 1172 : return aData.pAsSequence->getLength();
173 13276 : else if( aData.pAsInterface )
174 1839 : return 1;
175 11437 : return 0;
176 : }
177 :
178 524 : Sequence< Reference<XInterface> > OInterfaceContainerHelper::getElements() const SAL_THROW(())
179 : {
180 524 : MutexGuard aGuard( rMutex );
181 524 : if( bIsList )
182 31 : return *aData.pAsSequence;
183 493 : else if( aData.pAsInterface )
184 : {
185 470 : Reference<XInterface> x( aData.pAsInterface );
186 470 : return Sequence< Reference< XInterface > >( &x, 1 );
187 : }
188 23 : return Sequence< Reference< XInterface > >();
189 : }
190 :
191 1053 : void OInterfaceContainerHelper::copyAndResetInUse() SAL_THROW(())
192 : {
193 : OSL_ENSURE( bInUse, "OInterfaceContainerHelper not in use" );
194 1053 : if( bInUse )
195 : {
196 : // this should be the worst case. If a iterator is active
197 : // and a new Listener is added.
198 1053 : if( bIsList )
199 1053 : aData.pAsSequence = new Sequence< Reference< XInterface > >( *aData.pAsSequence );
200 0 : else if( aData.pAsInterface )
201 0 : aData.pAsInterface->acquire();
202 :
203 1053 : bInUse = sal_False;
204 : }
205 1053 : }
206 :
207 158636 : sal_Int32 OInterfaceContainerHelper::addInterface( const Reference<XInterface> & rListener ) SAL_THROW(())
208 : {
209 : OSL_ASSERT( rListener.is() );
210 158636 : MutexGuard aGuard( rMutex );
211 158636 : if( bInUse )
212 178 : copyAndResetInUse();
213 :
214 158636 : if( bIsList )
215 : {
216 55436 : sal_Int32 nLen = aData.pAsSequence->getLength();
217 55436 : realloc( *aData.pAsSequence, nLen +1 );
218 55436 : aData.pAsSequence->getArray()[ nLen ] = rListener;
219 55436 : return nLen +1;
220 : }
221 103200 : else if( aData.pAsInterface )
222 : {
223 33057 : Sequence< Reference< XInterface > > * pSeq = new Sequence< Reference< XInterface > >( 2 );
224 33057 : Reference<XInterface> * pArray = pSeq->getArray();
225 33057 : pArray[0] = aData.pAsInterface;
226 33057 : pArray[1] = rListener;
227 33057 : aData.pAsInterface->release();
228 33057 : aData.pAsSequence = pSeq;
229 33057 : bIsList = sal_True;
230 33057 : return 2;
231 : }
232 : else
233 : {
234 70143 : aData.pAsInterface = rListener.get();
235 70143 : if( rListener.is() )
236 70143 : rListener->acquire();
237 70143 : return 1;
238 158636 : }
239 : }
240 :
241 135899 : sal_Int32 OInterfaceContainerHelper::removeInterface( const Reference<XInterface> & rListener ) SAL_THROW(())
242 : {
243 : OSL_ASSERT( rListener.is() );
244 135899 : MutexGuard aGuard( rMutex );
245 135899 : if( bInUse )
246 874 : copyAndResetInUse();
247 :
248 135899 : if( bIsList )
249 : {
250 80406 : const Reference<XInterface> * pL = aData.pAsSequence->getConstArray();
251 80406 : sal_Int32 nLen = aData.pAsSequence->getLength();
252 : sal_Int32 i;
253 186476 : 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 186331 : if( pL[i].get() == rListener.get() )
258 : {
259 80261 : sequenceRemoveElementAt( *aData.pAsSequence, i );
260 80261 : break;
261 : }
262 : }
263 :
264 80406 : if( i == nLen )
265 : {
266 : // interface not found, use the correct compare method
267 1901 : for( i = 0; i < nLen; i++ )
268 : {
269 1756 : if( pL[i] == rListener )
270 : {
271 0 : sequenceRemoveElementAt(*aData.pAsSequence, i );
272 0 : break;
273 : }
274 : }
275 : }
276 :
277 80406 : if( aData.pAsSequence->getLength() == 1 )
278 : {
279 31101 : XInterface * p = aData.pAsSequence->getConstArray()[0].get();
280 31101 : p->acquire();
281 31101 : delete aData.pAsSequence;
282 31101 : aData.pAsInterface = p;
283 31101 : bIsList = sal_False;
284 31101 : return 1;
285 : }
286 : else
287 49305 : return aData.pAsSequence->getLength();
288 : }
289 55493 : else if( aData.pAsInterface && Reference<XInterface>( aData.pAsInterface ) == rListener )
290 : {
291 55358 : aData.pAsInterface->release();
292 55358 : aData.pAsInterface = 0;
293 : }
294 55493 : return aData.pAsInterface ? 1 : 0;
295 : }
296 :
297 25634 : void OInterfaceContainerHelper::disposeAndClear( const EventObject & rEvt ) SAL_THROW(())
298 : {
299 25634 : ClearableMutexGuard aGuard( rMutex );
300 25634 : OInterfaceIteratorHelper aIt( *this );
301 : // Release container, in case new entries come while disposing
302 : OSL_ENSURE( !bIsList || bInUse, "OInterfaceContainerHelper not in use" );
303 25634 : if( !bIsList && aData.pAsInterface )
304 5212 : aData.pAsInterface->release();
305 : // set the member to null, use the iterator to delete the values
306 25634 : aData.pAsInterface = NULL;
307 25634 : bIsList = sal_False;
308 25634 : bInUse = sal_False;
309 25634 : aGuard.clear();
310 58794 : while( aIt.hasMoreElements() )
311 : {
312 : try
313 : {
314 7526 : Reference<XEventListener > xLst( aIt.next(), UNO_QUERY );
315 7526 : if( xLst.is() )
316 7326 : xLst->disposing( rEvt );
317 : }
318 0 : 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 25634 : }
324 25634 : }
325 :
326 :
327 1 : void OInterfaceContainerHelper::clear() SAL_THROW(())
328 : {
329 1 : ClearableMutexGuard aGuard( rMutex );
330 1 : OInterfaceIteratorHelper aIt( *this );
331 : // Release container, in case new entries come while disposing
332 : OSL_ENSURE( !bIsList || bInUse, "OInterfaceContainerHelper not in use" );
333 1 : if( !bIsList && aData.pAsInterface )
334 0 : aData.pAsInterface->release();
335 : // set the member to null, use the iterator to delete the values
336 1 : aData.pAsInterface = 0;
337 1 : bIsList = sal_False;
338 1 : bInUse = sal_False;
339 : // release mutex before aIt destructor call
340 1 : aGuard.clear();
341 1 : }
342 :
343 : // specialized class for type
344 :
345 : typedef ::std::vector< std::pair < Type , void* > > t_type2ptr;
346 :
347 57758 : OMultiTypeInterfaceContainerHelper::OMultiTypeInterfaceContainerHelper( Mutex & rMutex_ )
348 : SAL_THROW(())
349 57758 : : rMutex( rMutex_ )
350 : {
351 57758 : m_pMap = new t_type2ptr();
352 57758 : }
353 44222 : OMultiTypeInterfaceContainerHelper::~OMultiTypeInterfaceContainerHelper()
354 : SAL_THROW(())
355 : {
356 44222 : t_type2ptr * pMap = (t_type2ptr *)m_pMap;
357 44222 : t_type2ptr::iterator iter = pMap->begin();
358 44222 : t_type2ptr::iterator end = pMap->end();
359 :
360 96495 : while( iter != end )
361 : {
362 8051 : delete (OInterfaceContainerHelper*)(*iter).second;
363 8051 : (*iter).second = 0;
364 8051 : ++iter;
365 : }
366 44222 : delete pMap;
367 44222 : }
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 132260 : static t_type2ptr::iterator findType(t_type2ptr *pMap, const Type & rKey )
403 : {
404 132260 : t_type2ptr::iterator iter = pMap->begin();
405 132260 : t_type2ptr::iterator end = pMap->end();
406 :
407 305023 : while( iter != end )
408 : {
409 76277 : if (iter->first == rKey)
410 35774 : break;
411 40503 : ++iter;
412 : }
413 132260 : return iter;
414 : }
415 :
416 109127 : OInterfaceContainerHelper * OMultiTypeInterfaceContainerHelper::getContainer( const Type & rKey ) const
417 : SAL_THROW(())
418 : {
419 109127 : ::osl::MutexGuard aGuard( rMutex );
420 :
421 109127 : t_type2ptr * pMap = (t_type2ptr *)m_pMap;
422 109127 : t_type2ptr::iterator iter = findType( pMap, rKey );
423 109127 : if( iter != pMap->end() )
424 25059 : return (OInterfaceContainerHelper*) (*iter).second;
425 84068 : return 0;
426 : }
427 17548 : sal_Int32 OMultiTypeInterfaceContainerHelper::addInterface(
428 : const Type & rKey, const Reference< XInterface > & rListener )
429 : SAL_THROW(())
430 : {
431 17548 : ::osl::MutexGuard aGuard( rMutex );
432 17548 : t_type2ptr * pMap = (t_type2ptr *)m_pMap;
433 17548 : t_type2ptr::iterator iter = findType( pMap, rKey );
434 17548 : if( iter == pMap->end() )
435 : {
436 12418 : OInterfaceContainerHelper * pLC = new OInterfaceContainerHelper( rMutex );
437 12418 : pMap->push_back(std::pair<Type, void*>(rKey, pLC));
438 12418 : return pLC->addInterface( rListener );
439 : }
440 : else
441 5130 : return ((OInterfaceContainerHelper*)(*iter).second)->addInterface( rListener );
442 : }
443 5585 : sal_Int32 OMultiTypeInterfaceContainerHelper::removeInterface(
444 : const Type & rKey, const Reference< XInterface > & rListener )
445 : SAL_THROW(())
446 : {
447 5585 : ::osl::MutexGuard aGuard( rMutex );
448 :
449 : // search container with id nUik
450 5585 : t_type2ptr * pMap = (t_type2ptr *)m_pMap;
451 5585 : t_type2ptr::iterator iter = findType( pMap, rKey );
452 : // container found?
453 5585 : if( iter != pMap->end() )
454 5585 : return ((OInterfaceContainerHelper*)(*iter).second)->removeInterface( rListener );
455 :
456 : // no container with this id. Always return 0
457 0 : return 0;
458 : }
459 26314 : void OMultiTypeInterfaceContainerHelper::disposeAndClear( const EventObject & rEvt )
460 : SAL_THROW(())
461 : {
462 26314 : t_type2ptr::size_type nSize = 0;
463 26314 : OInterfaceContainerHelper ** ppListenerContainers = NULL;
464 : {
465 26314 : ::osl::MutexGuard aGuard( rMutex );
466 26314 : t_type2ptr * pMap = (t_type2ptr *)m_pMap;
467 26314 : nSize = pMap->size();
468 26314 : if( nSize )
469 : {
470 : typedef OInterfaceContainerHelper* ppp;
471 4595 : ppListenerContainers = new ppp[nSize];
472 : //ppListenerContainers = new (ListenerContainer*)[nSize];
473 :
474 4595 : t_type2ptr::iterator iter = pMap->begin();
475 4595 : t_type2ptr::iterator end = pMap->end();
476 :
477 4595 : t_type2ptr::size_type i = 0;
478 15013 : while( iter != end )
479 : {
480 5823 : ppListenerContainers[i++] = (OInterfaceContainerHelper*)(*iter).second;
481 5823 : ++iter;
482 : }
483 26314 : }
484 : }
485 :
486 : // create a copy, because do not fire event in a guarded section
487 32137 : for( t_type2ptr::size_type i = 0;
488 : i < nSize; i++ )
489 : {
490 5823 : if( ppListenerContainers[i] )
491 5823 : ppListenerContainers[i]->disposeAndClear( rEvt );
492 : }
493 :
494 26314 : delete [] ppListenerContainers;
495 26314 : }
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 192 : static t_long2ptr::iterator findLong(t_long2ptr *pMap, sal_Int32 nKey )
516 : {
517 192 : t_long2ptr::iterator iter = pMap->begin();
518 192 : t_long2ptr::iterator end = pMap->end();
519 :
520 747 : while( iter != end )
521 : {
522 448 : if (iter->first == nKey)
523 85 : break;
524 363 : ++iter;
525 : }
526 192 : return iter;
527 : }
528 :
529 12389 : OMultiTypeInterfaceContainerHelperInt32::OMultiTypeInterfaceContainerHelperInt32( Mutex & rMutex_ )
530 : SAL_THROW(())
531 : : m_pMap( NULL )
532 12389 : , rMutex( rMutex_ )
533 : {
534 : // delay pMap allocation until necessary.
535 12389 : }
536 7065 : OMultiTypeInterfaceContainerHelperInt32::~OMultiTypeInterfaceContainerHelperInt32()
537 : SAL_THROW(())
538 : {
539 7065 : if (!m_pMap)
540 : return;
541 :
542 12 : t_long2ptr * pMap = (t_long2ptr *)m_pMap;
543 12 : t_long2ptr::iterator iter = pMap->begin();
544 12 : t_long2ptr::iterator end = pMap->end();
545 :
546 50 : while( iter != end )
547 : {
548 26 : delete (OInterfaceContainerHelper*)(*iter).second;
549 26 : (*iter).second = 0;
550 26 : ++iter;
551 : }
552 12 : delete pMap;
553 7065 : }
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 4649 : OInterfaceContainerHelper * OMultiTypeInterfaceContainerHelperInt32::getContainer( const sal_Int32 & rKey ) const
588 : SAL_THROW(())
589 : {
590 4649 : ::osl::MutexGuard aGuard( rMutex );
591 :
592 4649 : if (!m_pMap)
593 4559 : return 0;
594 90 : t_long2ptr * pMap = (t_long2ptr *)m_pMap;
595 90 : t_long2ptr::iterator iter = findLong( pMap, rKey );
596 90 : if( iter != pMap->end() )
597 32 : return (OInterfaceContainerHelper*) (*iter).second;
598 58 : return 0;
599 : }
600 70 : sal_Int32 OMultiTypeInterfaceContainerHelperInt32::addInterface(
601 : const sal_Int32 & rKey, const Reference< XInterface > & rListener )
602 : SAL_THROW(())
603 : {
604 70 : ::osl::MutexGuard aGuard( rMutex );
605 70 : if (!m_pMap)
606 22 : m_pMap = new t_long2ptr();
607 70 : t_long2ptr * pMap = (t_long2ptr *)m_pMap;
608 70 : t_long2ptr::iterator iter = findLong( pMap, rKey );
609 70 : if( iter == pMap->end() )
610 : {
611 49 : OInterfaceContainerHelper * pLC = new OInterfaceContainerHelper( rMutex );
612 49 : pMap->push_back(std::pair< sal_Int32, void* >(rKey, pLC));
613 49 : return pLC->addInterface( rListener );
614 : }
615 : else
616 21 : return ((OInterfaceContainerHelper*)(*iter).second)->addInterface( rListener );
617 : }
618 32 : sal_Int32 OMultiTypeInterfaceContainerHelperInt32::removeInterface(
619 : const sal_Int32 & rKey, const Reference< XInterface > & rListener )
620 : SAL_THROW(())
621 : {
622 32 : ::osl::MutexGuard aGuard( rMutex );
623 :
624 32 : if (!m_pMap)
625 0 : return 0;
626 : // search container with id nUik
627 32 : t_long2ptr * pMap = (t_long2ptr *)m_pMap;
628 32 : t_long2ptr::iterator iter = findLong( pMap, rKey );
629 : // container found?
630 32 : if( iter != pMap->end() )
631 32 : return ((OInterfaceContainerHelper*)(*iter).second)->removeInterface( rListener );
632 :
633 : // no container with this id. Always return 0
634 0 : return 0;
635 : }
636 206 : void OMultiTypeInterfaceContainerHelperInt32::disposeAndClear( const EventObject & rEvt )
637 : SAL_THROW(())
638 : {
639 206 : t_long2ptr::size_type nSize = 0;
640 206 : OInterfaceContainerHelper ** ppListenerContainers = NULL;
641 : {
642 206 : ::osl::MutexGuard aGuard( rMutex );
643 206 : if (!m_pMap)
644 206 : return;
645 :
646 21 : t_long2ptr * pMap = (t_long2ptr *)m_pMap;
647 21 : nSize = pMap->size();
648 21 : if( nSize )
649 : {
650 : typedef OInterfaceContainerHelper* ppp;
651 21 : ppListenerContainers = new ppp[nSize];
652 :
653 21 : t_long2ptr::iterator iter = pMap->begin();
654 21 : t_long2ptr::iterator end = pMap->end();
655 :
656 21 : t_long2ptr::size_type i = 0;
657 81 : while( iter != end )
658 : {
659 39 : ppListenerContainers[i++] = (OInterfaceContainerHelper*)(*iter).second;
660 39 : ++iter;
661 : }
662 206 : }
663 : }
664 :
665 : // create a copy, because do not fire event in a guarded section
666 60 : for( t_long2ptr::size_type i = 0;
667 : i < nSize; i++ )
668 : {
669 39 : if( ppListenerContainers[i] )
670 39 : ppListenerContainers[i]->disposeAndClear( rEvt );
671 : }
672 :
673 21 : 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: */
|