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/scoped_array.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 3111459 : static void realloc( Sequence< Reference< XInterface > > & rSeq, sal_Int32 nNewLen )
43 : {
44 3111459 : rSeq.realloc( nNewLen );
45 3111459 : }
46 :
47 : /**
48 : * Remove an element from an interface sequence.
49 : */
50 4756405 : static void sequenceRemoveElementAt( Sequence< Reference< XInterface > > & rSeq, sal_Int32 index )
51 : {
52 4756405 : sal_Int32 nNewLen = rSeq.getLength() - 1;
53 :
54 4756405 : Sequence< Reference< XInterface > > aDestSeq( rSeq.getLength() - 1 );
55 : // getArray on a const sequence is faster
56 4756405 : const Reference< XInterface > * pSource = ((const Sequence< Reference< XInterface > > &)rSeq).getConstArray();
57 4756405 : Reference< XInterface > * pDest = aDestSeq.getArray();
58 4756405 : sal_Int32 i = 0;
59 10806330 : for( ; i < index; i++ )
60 6049925 : pDest[i] = pSource[i];
61 11489621 : for( sal_Int32 j = i ; j < nNewLen; j++ )
62 6733216 : pDest[j] = pSource[j+1];
63 4756405 : rSeq = aDestSeq;
64 4756405 : }
65 :
66 : #ifdef _MSC_VER
67 : #pragma warning( disable: 4786 )
68 : #endif
69 :
70 3776620 : OInterfaceIteratorHelper::OInterfaceIteratorHelper( OInterfaceContainerHelper & rCont_ )
71 3776620 : : rCont( rCont_ )
72 : {
73 3776620 : MutexGuard aGuard( rCont.rMutex );
74 3776620 : if( rCont.bInUse )
75 : // worst case, two iterators at the same time
76 105 : rCont.copyAndResetInUse();
77 3776620 : bIsList = rCont_.bIsList;
78 3776620 : aData = rCont_.aData;
79 3776620 : if( bIsList )
80 : {
81 213445 : rCont.bInUse = sal_True;
82 213445 : nRemain = aData.pAsSequence->getLength();
83 : }
84 3563175 : else if( aData.pAsInterface )
85 : {
86 2117503 : aData.pAsInterface->acquire();
87 2117503 : nRemain = 1;
88 : }
89 : else
90 1445672 : nRemain = 0;
91 3776620 : }
92 :
93 3776619 : OInterfaceIteratorHelper::~OInterfaceIteratorHelper()
94 : {
95 : bool bShared;
96 : {
97 3776619 : MutexGuard aGuard( rCont.rMutex );
98 : // bResetInUse protect the iterator against recursion
99 3776619 : bShared = aData.pAsSequence == rCont.aData.pAsSequence && rCont.bIsList;
100 3776619 : if( bShared )
101 : {
102 : OSL_ENSURE( rCont.bInUse, "OInterfaceContainerHelper must be in use" );
103 116780 : rCont.bInUse = sal_False;
104 3776619 : }
105 : }
106 :
107 3776619 : if( !bShared )
108 : {
109 3659839 : if( bIsList )
110 : // Sequence owned by the iterator
111 96664 : delete aData.pAsSequence;
112 3563175 : else if( aData.pAsInterface )
113 : // Interface is acquired by the iterator
114 2117503 : aData.pAsInterface->release();
115 : }
116 3776619 : }
117 :
118 2736854 : XInterface * OInterfaceIteratorHelper::next()
119 : {
120 2736854 : if( nRemain )
121 : {
122 2736854 : nRemain--;
123 2736854 : if( bIsList )
124 : // typecase to const,so the getArray method is faster
125 619361 : return aData.pAsSequence->getConstArray()[nRemain].get();
126 2117493 : else if( aData.pAsInterface )
127 2117493 : return aData.pAsInterface;
128 : }
129 : // exception
130 0 : return 0;
131 : }
132 :
133 14 : void OInterfaceIteratorHelper::remove()
134 : {
135 14 : if( bIsList )
136 : {
137 : OSL_ASSERT( nRemain >= 0 &&
138 : nRemain < aData.pAsSequence->getLength() );
139 5 : XInterface * p = aData.pAsSequence->getConstArray()[nRemain].get();
140 5 : rCont.removeInterface( * reinterpret_cast< const Reference< XInterface > * >( &p ) );
141 : }
142 : else
143 : {
144 : OSL_ASSERT( 0 == nRemain );
145 9 : rCont.removeInterface( * reinterpret_cast< const Reference< XInterface > * >(&aData.pAsInterface));
146 : }
147 14 : }
148 :
149 3558735 : OInterfaceContainerHelper::OInterfaceContainerHelper( Mutex & rMutex_ )
150 : : rMutex( rMutex_ )
151 : , bInUse( sal_False )
152 3558735 : , bIsList( sal_False )
153 : {
154 3558735 : }
155 :
156 3413099 : OInterfaceContainerHelper::~OInterfaceContainerHelper()
157 : {
158 : OSL_ENSURE( !bInUse, "~OInterfaceContainerHelper but is in use" );
159 3413099 : if( bIsList )
160 27 : delete aData.pAsSequence;
161 3413072 : else if( aData.pAsInterface )
162 20568 : aData.pAsInterface->release();
163 3413099 : }
164 :
165 623950 : sal_Int32 OInterfaceContainerHelper::getLength() const
166 : {
167 623950 : MutexGuard aGuard( rMutex );
168 623950 : if( bIsList )
169 28698 : return aData.pAsSequence->getLength();
170 595252 : else if( aData.pAsInterface )
171 55012 : return 1;
172 540240 : return 0;
173 : }
174 :
175 27120 : Sequence< Reference<XInterface> > OInterfaceContainerHelper::getElements() const
176 : {
177 27120 : MutexGuard aGuard( rMutex );
178 27120 : if( bIsList )
179 9146 : return *aData.pAsSequence;
180 17974 : else if( aData.pAsInterface )
181 : {
182 16626 : Reference<XInterface> x( aData.pAsInterface );
183 16626 : return Sequence< Reference< XInterface > >( &x, 1 );
184 : }
185 1348 : return Sequence< Reference< XInterface > >();
186 : }
187 :
188 76473 : void OInterfaceContainerHelper::copyAndResetInUse()
189 : {
190 : OSL_ENSURE( bInUse, "OInterfaceContainerHelper not in use" );
191 76473 : if( bInUse )
192 : {
193 : // this should be the worst case. If a iterator is active
194 : // and a new Listener is added.
195 76473 : if( bIsList )
196 76473 : aData.pAsSequence = new Sequence< Reference< XInterface > >( *aData.pAsSequence );
197 0 : else if( aData.pAsInterface )
198 0 : aData.pAsInterface->acquire();
199 :
200 76473 : bInUse = sal_False;
201 : }
202 76473 : }
203 :
204 7091591 : sal_Int32 OInterfaceContainerHelper::addInterface( const Reference<XInterface> & rListener )
205 : {
206 : OSL_ASSERT( rListener.is() );
207 7091591 : MutexGuard aGuard( rMutex );
208 7091591 : if( bInUse )
209 2803 : copyAndResetInUse();
210 :
211 7091591 : if( bIsList )
212 : {
213 3111459 : sal_Int32 nLen = aData.pAsSequence->getLength();
214 3111459 : realloc( *aData.pAsSequence, nLen +1 );
215 3111459 : aData.pAsSequence->getArray()[ nLen ] = rListener;
216 3111459 : return nLen +1;
217 : }
218 3980132 : else if( aData.pAsInterface )
219 : {
220 1685151 : Sequence< Reference< XInterface > > * pSeq = new Sequence< Reference< XInterface > >( 2 );
221 1685151 : Reference<XInterface> * pArray = pSeq->getArray();
222 1685151 : pArray[0] = aData.pAsInterface;
223 1685151 : pArray[1] = rListener;
224 1685151 : aData.pAsInterface->release();
225 1685151 : aData.pAsSequence = pSeq;
226 1685151 : bIsList = sal_True;
227 1685151 : return 2;
228 : }
229 : else
230 : {
231 2294981 : aData.pAsInterface = rListener.get();
232 2294981 : if( rListener.is() )
233 2294981 : rListener->acquire();
234 2294981 : return 1;
235 7091591 : }
236 : }
237 :
238 6914581 : sal_Int32 OInterfaceContainerHelper::removeInterface( const Reference<XInterface> & rListener )
239 : {
240 : OSL_ASSERT( rListener.is() );
241 6914581 : MutexGuard aGuard( rMutex );
242 6914581 : if( bInUse )
243 73565 : copyAndResetInUse();
244 :
245 6914581 : if( bIsList )
246 : {
247 4763351 : const Reference<XInterface> * pL = aData.pAsSequence->getConstArray();
248 4763351 : sal_Int32 nLen = aData.pAsSequence->getLength();
249 : sal_Int32 i;
250 10855931 : for( i = 0; i < nLen; i++ )
251 : {
252 : // It is not valid to compare the pointer directly, but it's faster.
253 10848984 : if( pL[i].get() == rListener.get() )
254 : {
255 4756404 : sequenceRemoveElementAt( *aData.pAsSequence, i );
256 4756404 : break;
257 : }
258 : }
259 :
260 4763351 : if( i == nLen )
261 : {
262 : // interface not found, use the correct compare method
263 49602 : for( i = 0; i < nLen; i++ )
264 : {
265 42656 : if( pL[i] == rListener )
266 : {
267 1 : sequenceRemoveElementAt(*aData.pAsSequence, i );
268 1 : break;
269 : }
270 : }
271 : }
272 :
273 4763351 : if( aData.pAsSequence->getLength() == 1 )
274 : {
275 1663335 : XInterface * p = aData.pAsSequence->getConstArray()[0].get();
276 1663335 : p->acquire();
277 1663335 : delete aData.pAsSequence;
278 1663335 : aData.pAsInterface = p;
279 1663335 : bIsList = sal_False;
280 1663335 : return 1;
281 : }
282 : else
283 3100016 : return aData.pAsSequence->getLength();
284 : }
285 2151230 : else if( aData.pAsInterface && Reference<XInterface>( aData.pAsInterface ) == rListener )
286 : {
287 2146086 : aData.pAsInterface->release();
288 2146086 : aData.pAsInterface = 0;
289 : }
290 2151230 : return aData.pAsInterface ? 1 : 0;
291 : }
292 :
293 1281756 : void OInterfaceContainerHelper::disposeAndClear( const EventObject & rEvt )
294 : {
295 1281756 : ClearableMutexGuard aGuard( rMutex );
296 2563512 : OInterfaceIteratorHelper aIt( *this );
297 : // Release container, in case new entries come while disposing
298 : OSL_ENSURE( !bIsList || bInUse, "OInterfaceContainerHelper not in use" );
299 1281756 : if( !bIsList && aData.pAsInterface )
300 101834 : aData.pAsInterface->release();
301 : // set the member to null, use the iterator to delete the values
302 1281756 : aData.pAsInterface = NULL;
303 1281756 : bIsList = sal_False;
304 1281756 : bInUse = sal_False;
305 1281756 : aGuard.clear();
306 2721604 : while( aIt.hasMoreElements() )
307 : {
308 : try
309 : {
310 158092 : Reference<XEventListener > xLst( aIt.next(), UNO_QUERY );
311 158092 : if( xLst.is() )
312 142479 : xLst->disposing( rEvt );
313 : }
314 3405 : catch ( RuntimeException & )
315 : {
316 : // be robust, if e.g. a remote bridge has disposed already.
317 : // there is no way to delegate the error to the caller :o(.
318 : }
319 1281756 : }
320 1281756 : }
321 :
322 :
323 57 : void OInterfaceContainerHelper::clear()
324 : {
325 57 : ClearableMutexGuard aGuard( rMutex );
326 114 : OInterfaceIteratorHelper aIt( *this );
327 : // Release container, in case new entries come while disposing
328 : OSL_ENSURE( !bIsList || bInUse, "OInterfaceContainerHelper not in use" );
329 57 : if( !bIsList && aData.pAsInterface )
330 9 : aData.pAsInterface->release();
331 : // set the member to null, use the iterator to delete the values
332 57 : aData.pAsInterface = 0;
333 57 : bIsList = sal_False;
334 57 : bInUse = sal_False;
335 : // release mutex before aIt destructor call
336 114 : aGuard.clear();
337 57 : }
338 :
339 : // specialized class for type
340 :
341 : typedef ::std::vector< std::pair < Type , void* > > t_type2ptr;
342 :
343 2105943 : OMultiTypeInterfaceContainerHelper::OMultiTypeInterfaceContainerHelper( Mutex & rMutex_ )
344 2105943 : : rMutex( rMutex_ )
345 : {
346 2105943 : m_pMap = new t_type2ptr();
347 2105943 : }
348 :
349 2087431 : OMultiTypeInterfaceContainerHelper::~OMultiTypeInterfaceContainerHelper()
350 : {
351 2087431 : t_type2ptr * pMap = static_cast<t_type2ptr *>(m_pMap);
352 2087431 : t_type2ptr::iterator iter = pMap->begin();
353 2087431 : t_type2ptr::iterator end = pMap->end();
354 :
355 4320926 : while( iter != end )
356 : {
357 146064 : delete static_cast<OInterfaceContainerHelper*>((*iter).second);
358 146064 : (*iter).second = 0;
359 146064 : ++iter;
360 : }
361 2087431 : delete pMap;
362 2087431 : }
363 :
364 0 : Sequence< Type > OMultiTypeInterfaceContainerHelper::getContainedTypes() const
365 : {
366 0 : t_type2ptr * pMap = static_cast<t_type2ptr *>(m_pMap);
367 : t_type2ptr::size_type nSize;
368 :
369 0 : ::osl::MutexGuard aGuard( rMutex );
370 0 : nSize = pMap->size();
371 0 : if( nSize )
372 : {
373 0 : ::com::sun::star::uno::Sequence< Type > aInterfaceTypes( nSize );
374 0 : Type * pArray = aInterfaceTypes.getArray();
375 :
376 0 : t_type2ptr::iterator iter = pMap->begin();
377 0 : t_type2ptr::iterator end = pMap->end();
378 :
379 0 : sal_Int32 i = 0;
380 0 : while( iter != end )
381 : {
382 : // are interfaces added to this container?
383 0 : if( static_cast<OInterfaceContainerHelper*>((*iter).second)->getLength() )
384 : // yes, put the type in the array
385 0 : pArray[i++] = (*iter).first;
386 0 : ++iter;
387 : }
388 0 : if( (t_type2ptr::size_type)i != nSize ) {
389 : // may be empty container, reduce the sequence to the right size
390 0 : aInterfaceTypes = ::com::sun::star::uno::Sequence< Type >( pArray, i );
391 : }
392 0 : return aInterfaceTypes;
393 : }
394 0 : return ::com::sun::star::uno::Sequence< Type >();
395 : }
396 :
397 1691695 : static t_type2ptr::iterator findType(t_type2ptr *pMap, const Type & rKey )
398 : {
399 1691695 : t_type2ptr::iterator iter = pMap->begin();
400 1691695 : t_type2ptr::iterator end = pMap->end();
401 :
402 4359691 : while( iter != end )
403 : {
404 1771155 : if (iter->first == rKey)
405 794854 : break;
406 976301 : ++iter;
407 : }
408 1691695 : return iter;
409 : }
410 :
411 1147649 : OInterfaceContainerHelper * OMultiTypeInterfaceContainerHelper::getContainer( const Type & rKey ) const
412 : {
413 1147649 : ::osl::MutexGuard aGuard( rMutex );
414 :
415 1147649 : t_type2ptr * pMap = static_cast<t_type2ptr *>(m_pMap);
416 1147649 : t_type2ptr::iterator iter = findType( pMap, rKey );
417 1147649 : if( iter != pMap->end() )
418 407704 : return static_cast<OInterfaceContainerHelper*>((*iter).second);
419 739945 : return 0;
420 : }
421 :
422 322838 : sal_Int32 OMultiTypeInterfaceContainerHelper::addInterface(
423 : const Type & rKey, const Reference< XInterface > & rListener )
424 : {
425 322838 : ::osl::MutexGuard aGuard( rMutex );
426 322838 : t_type2ptr * pMap = static_cast<t_type2ptr *>(m_pMap);
427 322838 : t_type2ptr::iterator iter = findType( pMap, rKey );
428 322838 : if( iter == pMap->end() )
429 : {
430 156888 : OInterfaceContainerHelper * pLC = new OInterfaceContainerHelper( rMutex );
431 156888 : pMap->push_back(std::pair<Type, void*>(rKey, pLC));
432 156888 : return pLC->addInterface( rListener );
433 : }
434 : else
435 165950 : return static_cast<OInterfaceContainerHelper*>((*iter).second)->addInterface( rListener );
436 : }
437 :
438 221208 : sal_Int32 OMultiTypeInterfaceContainerHelper::removeInterface(
439 : const Type & rKey, const Reference< XInterface > & rListener )
440 : {
441 221208 : ::osl::MutexGuard aGuard( rMutex );
442 :
443 : // search container with id nUik
444 221208 : t_type2ptr * pMap = static_cast<t_type2ptr *>(m_pMap);
445 221208 : t_type2ptr::iterator iter = findType( pMap, rKey );
446 : // container found?
447 221208 : if( iter != pMap->end() )
448 221200 : return static_cast<OInterfaceContainerHelper*>((*iter).second)->removeInterface( rListener );
449 :
450 : // no container with this id. Always return 0
451 8 : return 0;
452 : }
453 :
454 1551517 : void OMultiTypeInterfaceContainerHelper::disposeAndClear( const EventObject & rEvt )
455 : {
456 1551517 : t_type2ptr::size_type nSize = 0;
457 1551517 : boost::scoped_array<OInterfaceContainerHelper *> ppListenerContainers;
458 : {
459 1551517 : ::osl::MutexGuard aGuard( rMutex );
460 1551517 : t_type2ptr * pMap = static_cast<t_type2ptr *>(m_pMap);
461 1551517 : nSize = pMap->size();
462 1551517 : if( nSize )
463 : {
464 : typedef OInterfaceContainerHelper* ppp;
465 81656 : ppListenerContainers.reset(new ppp[nSize]);
466 : //ppListenerContainers = new (ListenerContainer*)[nSize];
467 :
468 81656 : t_type2ptr::iterator iter = pMap->begin();
469 81656 : t_type2ptr::iterator end = pMap->end();
470 :
471 81656 : t_type2ptr::size_type i = 0;
472 286035 : while( iter != end )
473 : {
474 122723 : ppListenerContainers[i++] = static_cast<OInterfaceContainerHelper*>((*iter).second);
475 122723 : ++iter;
476 : }
477 1551517 : }
478 : }
479 :
480 : // create a copy, because do not fire event in a guarded section
481 1674240 : for( t_type2ptr::size_type i = 0;
482 : i < nSize; i++ )
483 : {
484 122723 : if( ppListenerContainers[i] )
485 122723 : ppListenerContainers[i]->disposeAndClear( rEvt );
486 1551517 : }
487 1551517 : }
488 :
489 0 : void OMultiTypeInterfaceContainerHelper::clear()
490 : {
491 0 : ::osl::MutexGuard aGuard( rMutex );
492 0 : t_type2ptr * pMap = static_cast<t_type2ptr *>(m_pMap);
493 0 : t_type2ptr::iterator iter = pMap->begin();
494 0 : t_type2ptr::iterator end = pMap->end();
495 :
496 0 : while( iter != end )
497 : {
498 0 : static_cast<OInterfaceContainerHelper*>((*iter).second)->clear();
499 0 : ++iter;
500 0 : }
501 0 : }
502 :
503 : // specialized class for long
504 :
505 : typedef ::std::vector< std::pair < sal_Int32 , void* > > t_long2ptr;
506 :
507 29758 : static t_long2ptr::iterator findLong(t_long2ptr *pMap, sal_Int32 nKey )
508 : {
509 29758 : t_long2ptr::iterator iter = pMap->begin();
510 29758 : t_long2ptr::iterator end = pMap->end();
511 :
512 164408 : while( iter != end )
513 : {
514 116274 : if (iter->first == nKey)
515 11382 : break;
516 104892 : ++iter;
517 : }
518 29758 : return iter;
519 : }
520 :
521 646009 : OMultiTypeInterfaceContainerHelperInt32::OMultiTypeInterfaceContainerHelperInt32( Mutex & rMutex_ )
522 : : m_pMap( NULL )
523 646009 : , rMutex( rMutex_ )
524 : {
525 : // delay pMap allocation until necessary.
526 646009 : }
527 :
528 644561 : OMultiTypeInterfaceContainerHelperInt32::~OMultiTypeInterfaceContainerHelperInt32()
529 : {
530 644561 : if (!m_pMap)
531 642685 : return;
532 :
533 1876 : t_long2ptr * pMap = static_cast<t_long2ptr *>(m_pMap);
534 1876 : t_long2ptr::iterator iter = pMap->begin();
535 1876 : t_long2ptr::iterator end = pMap->end();
536 :
537 10930 : while( iter != end )
538 : {
539 7178 : delete static_cast<OInterfaceContainerHelper*>((*iter).second);
540 7178 : (*iter).second = 0;
541 7178 : ++iter;
542 : }
543 1876 : delete pMap;
544 644561 : }
545 :
546 0 : Sequence< sal_Int32 > OMultiTypeInterfaceContainerHelperInt32::getContainedTypes() const
547 : {
548 0 : t_long2ptr * pMap = static_cast<t_long2ptr *>(m_pMap);
549 : t_long2ptr::size_type nSize;
550 :
551 0 : ::osl::MutexGuard aGuard( rMutex );
552 0 : nSize = pMap ? pMap->size() : 0;
553 0 : if( nSize )
554 : {
555 0 : ::com::sun::star::uno::Sequence< sal_Int32 > aInterfaceTypes( nSize );
556 0 : sal_Int32 * pArray = aInterfaceTypes.getArray();
557 :
558 0 : t_long2ptr::iterator iter = pMap->begin();
559 0 : t_long2ptr::iterator end = pMap->end();
560 :
561 0 : sal_Int32 i = 0;
562 0 : while( iter != end )
563 : {
564 : // are interfaces added to this container?
565 0 : if( static_cast<OInterfaceContainerHelper*>((*iter).second)->getLength() )
566 : // yes, put the type in the array
567 0 : pArray[i++] = (*iter).first;
568 0 : ++iter;
569 : }
570 0 : if( (t_long2ptr::size_type)i != nSize ) {
571 : // may be empty container, reduce the sequence to the right size
572 0 : aInterfaceTypes = ::com::sun::star::uno::Sequence< sal_Int32 >( pArray, i );
573 : }
574 0 : return aInterfaceTypes;
575 : }
576 0 : return ::com::sun::star::uno::Sequence< sal_Int32 >();
577 : }
578 :
579 70351 : OInterfaceContainerHelper * OMultiTypeInterfaceContainerHelperInt32::getContainer( const sal_Int32 & rKey ) const
580 : {
581 70351 : ::osl::MutexGuard aGuard( rMutex );
582 :
583 70351 : if (!m_pMap)
584 56477 : return 0;
585 13874 : t_long2ptr * pMap = static_cast<t_long2ptr *>(m_pMap);
586 13874 : t_long2ptr::iterator iter = findLong( pMap, rKey );
587 13874 : if( iter != pMap->end() )
588 2994 : return static_cast<OInterfaceContainerHelper*>((*iter).second);
589 10880 : return 0;
590 : }
591 :
592 10466 : sal_Int32 OMultiTypeInterfaceContainerHelperInt32::addInterface(
593 : const sal_Int32 & rKey, const Reference< XInterface > & rListener )
594 : {
595 10466 : ::osl::MutexGuard aGuard( rMutex );
596 10466 : if (!m_pMap)
597 1986 : m_pMap = new t_long2ptr();
598 10466 : t_long2ptr * pMap = static_cast<t_long2ptr *>(m_pMap);
599 10466 : t_long2ptr::iterator iter = findLong( pMap, rKey );
600 10466 : if( iter == pMap->end() )
601 : {
602 7465 : OInterfaceContainerHelper * pLC = new OInterfaceContainerHelper( rMutex );
603 7465 : pMap->push_back(std::pair< sal_Int32, void* >(rKey, pLC));
604 7465 : return pLC->addInterface( rListener );
605 : }
606 : else
607 3001 : return static_cast<OInterfaceContainerHelper*>((*iter).second)->addInterface( rListener );
608 : }
609 :
610 5418 : sal_Int32 OMultiTypeInterfaceContainerHelperInt32::removeInterface(
611 : const sal_Int32 & rKey, const Reference< XInterface > & rListener )
612 : {
613 5418 : ::osl::MutexGuard aGuard( rMutex );
614 :
615 5418 : if (!m_pMap)
616 0 : return 0;
617 : // search container with id nUik
618 5418 : t_long2ptr * pMap = static_cast<t_long2ptr *>(m_pMap);
619 5418 : t_long2ptr::iterator iter = findLong( pMap, rKey );
620 : // container found?
621 5418 : if( iter != pMap->end() )
622 5387 : return static_cast<OInterfaceContainerHelper*>((*iter).second)->removeInterface( rListener );
623 :
624 : // no container with this id. Always return 0
625 31 : return 0;
626 : }
627 :
628 70004 : void OMultiTypeInterfaceContainerHelperInt32::disposeAndClear( const EventObject & rEvt )
629 : {
630 70004 : t_long2ptr::size_type nSize = 0;
631 70004 : boost::scoped_array<OInterfaceContainerHelper *> ppListenerContainers;
632 : {
633 70004 : ::osl::MutexGuard aGuard( rMutex );
634 70004 : if (!m_pMap)
635 138335 : return;
636 :
637 1673 : t_long2ptr * pMap = static_cast<t_long2ptr *>(m_pMap);
638 1673 : nSize = pMap->size();
639 1673 : if( nSize )
640 : {
641 : typedef OInterfaceContainerHelper* ppp;
642 1673 : ppListenerContainers.reset(new ppp[nSize]);
643 :
644 1673 : t_long2ptr::iterator iter = pMap->begin();
645 1673 : t_long2ptr::iterator end = pMap->end();
646 :
647 1673 : t_long2ptr::size_type i = 0;
648 10047 : while( iter != end )
649 : {
650 6701 : ppListenerContainers[i++] = static_cast<OInterfaceContainerHelper*>((*iter).second);
651 6701 : ++iter;
652 : }
653 1673 : }
654 : }
655 :
656 : // create a copy, because do not fire event in a guarded section
657 8374 : for( t_long2ptr::size_type i = 0;
658 : i < nSize; i++ )
659 : {
660 6701 : if( ppListenerContainers[i] )
661 6701 : ppListenerContainers[i]->disposeAndClear( rEvt );
662 1673 : }
663 : }
664 :
665 0 : void OMultiTypeInterfaceContainerHelperInt32::clear()
666 : {
667 0 : ::osl::MutexGuard aGuard( rMutex );
668 0 : if (!m_pMap)
669 0 : return;
670 0 : t_long2ptr * pMap = static_cast<t_long2ptr *>(m_pMap);
671 0 : t_long2ptr::iterator iter = pMap->begin();
672 0 : t_long2ptr::iterator end = pMap->end();
673 :
674 0 : while( iter != end )
675 : {
676 0 : static_cast<OInterfaceContainerHelper*>((*iter).second)->clear();
677 0 : ++iter;
678 0 : }
679 : }
680 :
681 : }
682 :
683 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|