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