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