Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <cppuhelper/interfacecontainer.hxx>
31 : : #include <cppuhelper/queryinterface.hxx>
32 : : #include <cppuhelper/propshlp.hxx>
33 : :
34 : : #include <osl/diagnose.h>
35 : : #include <osl/mutex.hxx>
36 : :
37 : : #include <boost/unordered_map.hpp>
38 : :
39 : : #include <com/sun/star/lang/XEventListener.hpp>
40 : :
41 : :
42 : : using namespace osl;
43 : : using namespace com::sun::star::uno;
44 : : using namespace com::sun::star::lang;
45 : :
46 : : namespace cppu
47 : : {
48 : : /**
49 : : * Reallocate the sequence.
50 : : */
51 : 662751 : static void realloc( Sequence< Reference< XInterface > > & rSeq, sal_Int32 nNewLen )
52 : : SAL_THROW(())
53 : : {
54 : 662751 : rSeq.realloc( nNewLen );
55 : 662751 : }
56 : :
57 : : /**
58 : : * Remove an element from an interface sequence.
59 : : */
60 : 998034 : static void sequenceRemoveElementAt( Sequence< Reference< XInterface > > & rSeq, sal_Int32 index )
61 : : SAL_THROW(())
62 : : {
63 : 998034 : sal_Int32 nNewLen = rSeq.getLength() - 1;
64 : :
65 [ + - ]: 998034 : Sequence< Reference< XInterface > > aDestSeq( rSeq.getLength() - 1 );
66 : : // getArray on a const sequence is faster
67 : 998034 : const Reference< XInterface > * pSource = ((const Sequence< Reference< XInterface > > &)rSeq).getConstArray();
68 [ + - ]: 998034 : Reference< XInterface > * pDest = aDestSeq.getArray();
69 : 998034 : sal_Int32 i = 0;
70 [ + + ]: 3029399 : for( ; i < index; i++ )
71 [ + - ]: 2031365 : pDest[i] = pSource[i];
72 [ + + ]: 4047905 : for( sal_Int32 j = i ; j < nNewLen; j++ )
73 [ + - ]: 3049871 : pDest[j] = pSource[j+1];
74 [ + - ][ + - ]: 998034 : rSeq = aDestSeq;
75 : 998034 : }
76 : :
77 : : #ifdef _MSC_VER
78 : : #pragma warning( disable: 4786 )
79 : : #endif
80 : :
81 : 1839068 : OInterfaceIteratorHelper::OInterfaceIteratorHelper( OInterfaceContainerHelper & rCont_ )
82 : : SAL_THROW(())
83 : 1839068 : : rCont( rCont_ )
84 : : {
85 [ + - ]: 1839067 : MutexGuard aGuard( rCont.rMutex );
86 [ + + ]: 1839068 : if( rCont.bInUse )
87 : : // worst case, two iterators at the same time
88 [ + - ]: 104 : rCont.copyAndResetInUse();
89 : 1839068 : bIsList = rCont_.bIsList;
90 : 1839068 : aData = rCont_.aData;
91 [ + + ]: 1839068 : if( bIsList )
92 : : {
93 : 90445 : rCont.bInUse = sal_True;
94 : 90445 : nRemain = aData.pAsSequence->getLength();
95 : : }
96 [ + + ]: 1748623 : else if( aData.pAsInterface )
97 : : {
98 : 915486 : aData.pAsInterface->acquire();
99 : 915486 : nRemain = 1;
100 : : }
101 : : else
102 [ + - ]: 1839068 : nRemain = 0;
103 : 1839068 : }
104 : :
105 : 1839068 : OInterfaceIteratorHelper::~OInterfaceIteratorHelper() SAL_THROW(())
106 : : {
107 : : sal_Bool bShared;
108 : : {
109 [ + - ]: 1839068 : MutexGuard aGuard( rCont.rMutex );
110 : : // bResetInUse protect the iterator against recursion
111 [ + + ][ + + ]: 1839068 : bShared = aData.pAsSequence == rCont.aData.pAsSequence && rCont.bIsList;
112 [ + + ]: 1839068 : if( bShared )
113 : : {
114 : : OSL_ENSURE( rCont.bInUse, "OInterfaceContainerHelper must be in use" );
115 : 69234 : rCont.bInUse = sal_False;
116 [ + - ]: 1839068 : }
117 : : }
118 : :
119 [ + + ]: 1839068 : if( !bShared )
120 : : {
121 [ + + ]: 1769834 : if( bIsList )
122 : : // Sequence owned by the iterator
123 [ + - ]: 21211 : delete aData.pAsSequence;
124 [ + + ]: 1748623 : else if( aData.pAsInterface )
125 : : // Interface is acquired by the iterator
126 : 915486 : aData.pAsInterface->release();
127 : : }
128 : 1839068 : }
129 : :
130 : 1298348 : XInterface * OInterfaceIteratorHelper::next() SAL_THROW(())
131 : : {
132 [ + + ]: 1298348 : if( nRemain )
133 : : {
134 : 1298347 : nRemain--;
135 [ + + ]: 1298347 : if( bIsList )
136 : : // typecase to const,so the getArray method is faster
137 : 382868 : return aData.pAsSequence->getConstArray()[nRemain].get();
138 [ + ]: 915479 : else if( aData.pAsInterface )
139 : 915480 : return aData.pAsInterface;
140 : : }
141 : : // exception
142 : 1298347 : return 0;
143 : : }
144 : :
145 : 19 : void OInterfaceIteratorHelper::remove() SAL_THROW(())
146 : : {
147 [ + + ]: 19 : if( bIsList )
148 : : {
149 : : OSL_ASSERT( nRemain >= 0 &&
150 : : nRemain < aData.pAsSequence->getLength() );
151 [ + - ]: 2 : XInterface * p = aData.pAsSequence->getConstArray()[nRemain].get();
152 [ + - ]: 2 : rCont.removeInterface( * reinterpret_cast< const Reference< XInterface > * >( &p ) );
153 : : }
154 : : else
155 : : {
156 : : OSL_ASSERT( 0 == nRemain );
157 : 17 : rCont.removeInterface( * reinterpret_cast< const Reference< XInterface > * >(&aData.pAsInterface));
158 : : }
159 : 19 : }
160 : :
161 : 1696895 : OInterfaceContainerHelper::OInterfaceContainerHelper( Mutex & rMutex_ ) SAL_THROW(())
162 : : : rMutex( rMutex_ )
163 : : , bInUse( sal_False )
164 : 1696895 : , bIsList( sal_False )
165 : : {
166 : 1696895 : }
167 : :
168 : 1633226 : OInterfaceContainerHelper::~OInterfaceContainerHelper() SAL_THROW(())
169 : : {
170 : : OSL_ENSURE( !bInUse, "~OInterfaceContainerHelper but is in use" );
171 [ + + ]: 1633226 : if( bIsList )
172 [ + - ]: 54 : delete aData.pAsSequence;
173 [ + + ]: 1633172 : else if( aData.pAsInterface )
174 : 9732 : aData.pAsInterface->release();
175 : 1633226 : }
176 : :
177 : 359224 : sal_Int32 OInterfaceContainerHelper::getLength() const SAL_THROW(())
178 : : {
179 [ + - ]: 359224 : MutexGuard aGuard( rMutex );
180 [ + + ]: 359224 : if( bIsList )
181 : 20994 : return aData.pAsSequence->getLength();
182 [ + + ]: 338230 : else if( aData.pAsInterface )
183 : 40291 : return 1;
184 [ + - ]: 359224 : return 0;
185 : : }
186 : :
187 : 7494 : Sequence< Reference<XInterface> > OInterfaceContainerHelper::getElements() const SAL_THROW(())
188 : : {
189 [ + - ]: 7494 : MutexGuard aGuard( rMutex );
190 [ + + ]: 7494 : if( bIsList )
191 [ + - ]: 729 : return *aData.pAsSequence;
192 [ + + ]: 6765 : else if( aData.pAsInterface )
193 : : {
194 [ + - ]: 6288 : Reference<XInterface> x( aData.pAsInterface );
195 [ + - ]: 6288 : return Sequence< Reference< XInterface > >( &x, 1 );
196 : : }
197 [ + - ][ + - ]: 7494 : return Sequence< Reference< XInterface > >();
198 : : }
199 : :
200 : 11567 : void OInterfaceContainerHelper::copyAndResetInUse() SAL_THROW(())
201 : : {
202 : : OSL_ENSURE( bInUse, "OInterfaceContainerHelper not in use" );
203 [ + - ]: 11567 : if( bInUse )
204 : : {
205 : : // this should be the worst case. If a iterator is active
206 : : // and a new Listener is added.
207 [ + - ]: 11567 : if( bIsList )
208 [ + - ]: 11567 : aData.pAsSequence = new Sequence< Reference< XInterface > >( *aData.pAsSequence );
209 [ # # ]: 0 : else if( aData.pAsInterface )
210 : 0 : aData.pAsInterface->acquire();
211 : :
212 : 11567 : bInUse = sal_False;
213 : : }
214 : 11567 : }
215 : :
216 : 2072986 : sal_Int32 OInterfaceContainerHelper::addInterface( const Reference<XInterface> & rListener ) SAL_THROW(())
217 : : {
218 : : OSL_ASSERT( rListener.is() );
219 [ + - ]: 2072986 : MutexGuard aGuard( rMutex );
220 [ + + ]: 2072986 : if( bInUse )
221 [ + - ]: 68 : copyAndResetInUse();
222 : :
223 [ + + ]: 2072986 : if( bIsList )
224 : : {
225 : 662751 : sal_Int32 nLen = aData.pAsSequence->getLength();
226 [ + - ]: 662751 : realloc( *aData.pAsSequence, nLen +1 );
227 [ + - ][ + - ]: 662751 : aData.pAsSequence->getArray()[ nLen ] = rListener;
228 : 662751 : return nLen +1;
229 : : }
230 [ + + ]: 1410235 : else if( aData.pAsInterface )
231 : : {
232 [ + - ]: 362243 : Sequence< Reference< XInterface > > * pSeq = new Sequence< Reference< XInterface > >( 2 );
233 [ + - ]: 362243 : Reference<XInterface> * pArray = pSeq->getArray();
234 [ + - ]: 362243 : pArray[0] = aData.pAsInterface;
235 [ + - ]: 362243 : pArray[1] = rListener;
236 : 362243 : aData.pAsInterface->release();
237 : 362243 : aData.pAsSequence = pSeq;
238 : 362243 : bIsList = sal_True;
239 : 362243 : return 2;
240 : : }
241 : : else
242 : : {
243 [ + - ]: 1047992 : aData.pAsInterface = rListener.get();
244 [ + - ]: 1047992 : if( rListener.is() )
245 [ + - ]: 1047992 : rListener->acquire();
246 : 1047992 : return 1;
247 [ + - ]: 2072986 : }
248 : : }
249 : :
250 : 1967365 : sal_Int32 OInterfaceContainerHelper::removeInterface( const Reference<XInterface> & rListener ) SAL_THROW(())
251 : : {
252 : : OSL_ASSERT( rListener.is() );
253 [ + - ]: 1967365 : MutexGuard aGuard( rMutex );
254 [ + + ]: 1967365 : if( bInUse )
255 [ + - ]: 11395 : copyAndResetInUse();
256 : :
257 [ + + ]: 1967365 : if( bIsList )
258 : : {
259 : 1002197 : const Reference<XInterface> * pL = aData.pAsSequence->getConstArray();
260 : 1002197 : sal_Int32 nLen = aData.pAsSequence->getLength();
261 : : sal_Int32 i;
262 [ + + ]: 3058590 : for( i = 0; i < nLen; i++ )
263 : : {
264 : : // It is not valid to compare the Pointer direkt, but is is is much
265 : : // more faster.
266 [ + - ][ + - ]: 3054425 : if( pL[i].get() == rListener.get() )
[ + + ]
267 : : {
268 [ + - ]: 998032 : sequenceRemoveElementAt( *aData.pAsSequence, i );
269 : 998032 : break;
270 : : }
271 : : }
272 : :
273 [ + + ]: 1002197 : if( i == nLen )
274 : : {
275 : : // interface not found, use the correct compare method
276 [ + + ]: 29195 : for( i = 0; i < nLen; i++ )
277 : : {
278 [ + - ][ + + ]: 25030 : if( pL[i] == rListener )
279 : : {
280 [ + - ]: 2 : sequenceRemoveElementAt(*aData.pAsSequence, i );
281 : 2 : break;
282 : : }
283 : : }
284 : : }
285 : :
286 [ + + ]: 1002197 : if( aData.pAsSequence->getLength() == 1 )
287 : : {
288 [ + - ]: 349872 : XInterface * p = aData.pAsSequence->getConstArray()[0].get();
289 : 349872 : p->acquire();
290 [ + - ][ + - ]: 349872 : delete aData.pAsSequence;
291 : 349872 : aData.pAsInterface = p;
292 : 349872 : bIsList = sal_False;
293 : 349872 : return 1;
294 : : }
295 : : else
296 : 652325 : return aData.pAsSequence->getLength();
297 : : }
298 [ + + ][ + - ]: 965168 : else if( aData.pAsInterface && Reference<XInterface>( aData.pAsInterface ) == rListener )
[ + - ][ + + ]
[ + + ]
[ + + # # ]
299 : : {
300 : 961879 : aData.pAsInterface->release();
301 : 961879 : aData.pAsInterface = 0;
302 : : }
303 [ + + ][ + - ]: 1967365 : return aData.pAsInterface ? 1 : 0;
304 : : }
305 : :
306 : 711712 : void OInterfaceContainerHelper::disposeAndClear( const EventObject & rEvt ) SAL_THROW(())
307 : : {
308 [ + - ]: 711712 : ClearableMutexGuard aGuard( rMutex );
309 [ + - ]: 711712 : OInterfaceIteratorHelper aIt( *this );
310 : : // Release container, in case new entries come while disposing
311 : : OSL_ENSURE( !bIsList || bInUse, "OInterfaceContainerHelper not in use" );
312 [ + + ][ + + ]: 711712 : if( !bIsList && aData.pAsInterface )
313 : 48367 : aData.pAsInterface->release();
314 : : // set the member to null, use the iterator to delete the values
315 : 711712 : aData.pAsInterface = NULL;
316 : 711712 : bIsList = sal_False;
317 : 711712 : bInUse = sal_False;
318 [ + - ]: 711712 : aGuard.clear();
319 [ + + ]: 789108 : while( aIt.hasMoreElements() )
320 : : {
321 : : try
322 : : {
323 [ + - ][ + - ]: 77396 : Reference<XEventListener > xLst( aIt.next(), UNO_QUERY );
324 [ + + ]: 77396 : if( xLst.is() )
325 [ + - ][ + + ]: 77396 : xLst->disposing( rEvt );
[ - + ]
326 : : }
327 [ + - ]: 3676 : catch ( RuntimeException & )
328 : : {
329 : : // be robust, if e.g. a remote bridge has disposed already.
330 : : // there is no way to delegate the error to the caller :o(.
331 : : }
332 [ + - ][ + - ]: 711712 : }
333 : 711712 : }
334 : :
335 : :
336 : 13 : void OInterfaceContainerHelper::clear() SAL_THROW(())
337 : : {
338 [ + - ]: 13 : ClearableMutexGuard aGuard( rMutex );
339 [ + - ]: 13 : OInterfaceIteratorHelper aIt( *this );
340 : : // Release container, in case new entries come while disposing
341 : : OSL_ENSURE( !bIsList || bInUse, "OInterfaceContainerHelper not in use" );
342 [ + + ][ + - ]: 13 : if( !bIsList && aData.pAsInterface )
343 : 6 : aData.pAsInterface->release();
344 : : // set the member to null, use the iterator to delete the values
345 : 13 : aData.pAsInterface = 0;
346 : 13 : bIsList = sal_False;
347 : 13 : bInUse = sal_False;
348 : : // release mutex before aIt destructor call
349 [ + - ][ + - ]: 13 : aGuard.clear();
[ + - ]
350 : 13 : }
351 : :
352 : : // specialized class for type
353 : :
354 : : typedef ::std::vector< std::pair < Type , void* > > t_type2ptr;
355 : :
356 : 1309459 : OMultiTypeInterfaceContainerHelper::OMultiTypeInterfaceContainerHelper( Mutex & rMutex_ )
357 : : SAL_THROW(())
358 : 1309459 : : rMutex( rMutex_ )
359 : : {
360 [ + - ]: 1309459 : m_pMap = new t_type2ptr();
361 : 1309459 : }
362 : 1289369 : OMultiTypeInterfaceContainerHelper::~OMultiTypeInterfaceContainerHelper()
363 : : SAL_THROW(())
364 : : {
365 : 1289369 : t_type2ptr * pMap = (t_type2ptr *)m_pMap;
366 : 1289369 : t_type2ptr::iterator iter = pMap->begin();
367 : 1289369 : t_type2ptr::iterator end = pMap->end();
368 : :
369 [ + - ][ + + ]: 1394201 : while( iter != end )
370 : : {
371 [ + - ][ + - ]: 104832 : delete (OInterfaceContainerHelper*)(*iter).second;
372 : 104832 : (*iter).second = 0;
373 : 104832 : ++iter;
374 : : }
375 [ + - ]: 1289369 : delete pMap;
376 : 1289369 : }
377 : 0 : Sequence< Type > OMultiTypeInterfaceContainerHelper::getContainedTypes() const
378 : : SAL_THROW(())
379 : : {
380 : 0 : t_type2ptr * pMap = (t_type2ptr *)m_pMap;
381 : : t_type2ptr::size_type nSize;
382 : :
383 [ # # ]: 0 : ::osl::MutexGuard aGuard( rMutex );
384 : 0 : nSize = pMap->size();
385 [ # # ]: 0 : if( nSize )
386 : : {
387 [ # # ]: 0 : ::com::sun::star::uno::Sequence< Type > aInterfaceTypes( nSize );
388 [ # # ]: 0 : Type * pArray = aInterfaceTypes.getArray();
389 : :
390 : 0 : t_type2ptr::iterator iter = pMap->begin();
391 : 0 : t_type2ptr::iterator end = pMap->end();
392 : :
393 : 0 : sal_Int32 i = 0;
394 [ # # ][ # # ]: 0 : while( iter != end )
395 : : {
396 : : // are interfaces added to this container?
397 [ # # ][ # # ]: 0 : if( ((OInterfaceContainerHelper*)(*iter).second)->getLength() )
398 : : // yes, put the type in the array
399 : 0 : pArray[i++] = (*iter).first;
400 : 0 : ++iter;
401 : : }
402 [ # # ]: 0 : if( (t_type2ptr::size_type)i != nSize ) {
403 : : // may be empty container, reduce the sequence to the right size
404 [ # # ][ # # ]: 0 : aInterfaceTypes = ::com::sun::star::uno::Sequence< Type >( pArray, i );
[ # # ]
405 : : }
406 [ # # ][ # # ]: 0 : return aInterfaceTypes;
407 : : }
408 [ # # ][ # # ]: 0 : return ::com::sun::star::uno::Sequence< Type >();
409 : : }
410 : :
411 : 1314874 : static t_type2ptr::iterator findType(t_type2ptr *pMap, const Type & rKey )
412 : : {
413 : 1314874 : t_type2ptr::iterator iter = pMap->begin();
414 : 1314874 : t_type2ptr::iterator end = pMap->end();
415 : :
416 [ + - ][ + + ]: 2622634 : while( iter != end )
417 : : {
418 [ + + ]: 1307760 : if (iter->first == rKey)
419 : 716311 : break;
420 : 591449 : ++iter;
421 : : }
422 : 1314874 : return iter;
423 : : }
424 : :
425 : 796499 : OInterfaceContainerHelper * OMultiTypeInterfaceContainerHelper::getContainer( const Type & rKey ) const
426 : : SAL_THROW(())
427 : : {
428 [ + - ]: 796499 : ::osl::MutexGuard aGuard( rMutex );
429 : :
430 : 796499 : t_type2ptr * pMap = (t_type2ptr *)m_pMap;
431 [ + - ]: 796499 : t_type2ptr::iterator iter = findType( pMap, rKey );
432 [ + - ][ + + ]: 796499 : if( iter != pMap->end() )
433 : 314492 : return (OInterfaceContainerHelper*) (*iter).second;
434 [ + - ]: 796499 : return 0;
435 : : }
436 : 293311 : sal_Int32 OMultiTypeInterfaceContainerHelper::addInterface(
437 : : const Type & rKey, const Reference< XInterface > & rListener )
438 : : SAL_THROW(())
439 : : {
440 [ + - ]: 293311 : ::osl::MutexGuard aGuard( rMutex );
441 : 293311 : t_type2ptr * pMap = (t_type2ptr *)m_pMap;
442 [ + - ]: 293311 : t_type2ptr::iterator iter = findType( pMap, rKey );
443 [ + - ][ + + ]: 293311 : if( iter == pMap->end() )
444 : : {
445 [ + - ]: 116556 : OInterfaceContainerHelper * pLC = new OInterfaceContainerHelper( rMutex );
446 [ + - ][ + - ]: 116556 : pMap->push_back(std::pair<Type, void*>(rKey, pLC));
447 [ + - ]: 116556 : return pLC->addInterface( rListener );
448 : : }
449 : : else
450 [ + - ][ + - ]: 293311 : return ((OInterfaceContainerHelper*)(*iter).second)->addInterface( rListener );
451 : : }
452 : 225064 : sal_Int32 OMultiTypeInterfaceContainerHelper::removeInterface(
453 : : const Type & rKey, const Reference< XInterface > & rListener )
454 : : SAL_THROW(())
455 : : {
456 [ + - ]: 225064 : ::osl::MutexGuard aGuard( rMutex );
457 : :
458 : : // search container with id nUik
459 : 225064 : t_type2ptr * pMap = (t_type2ptr *)m_pMap;
460 [ + - ]: 225064 : t_type2ptr::iterator iter = findType( pMap, rKey );
461 : : // container found?
462 [ + - ][ + - ]: 225064 : if( iter != pMap->end() )
463 [ + - ]: 225064 : return ((OInterfaceContainerHelper*)(*iter).second)->removeInterface( rListener );
464 : :
465 : : // no container with this id. Always return 0
466 [ + - ]: 225064 : return 0;
467 : : }
468 : 1101264 : void OMultiTypeInterfaceContainerHelper::disposeAndClear( const EventObject & rEvt )
469 : : SAL_THROW(())
470 : : {
471 : 1101264 : t_type2ptr::size_type nSize = 0;
472 : 1101264 : OInterfaceContainerHelper ** ppListenerContainers = NULL;
473 : : {
474 [ + - ]: 1101264 : ::osl::MutexGuard aGuard( rMutex );
475 : 1101264 : t_type2ptr * pMap = (t_type2ptr *)m_pMap;
476 : 1101264 : nSize = pMap->size();
477 [ + + ]: 1101264 : if( nSize )
478 : : {
479 : : typedef OInterfaceContainerHelper* ppp;
480 [ + - ]: 51458 : ppListenerContainers = new ppp[nSize];
481 : : //ppListenerContainers = new (ListenerContainer*)[nSize];
482 : :
483 : 51458 : t_type2ptr::iterator iter = pMap->begin();
484 : 51458 : t_type2ptr::iterator end = pMap->end();
485 : :
486 : 51458 : t_type2ptr::size_type i = 0;
487 [ + - ][ + + ]: 130117 : while( iter != end )
488 : : {
489 : 78659 : ppListenerContainers[i++] = (OInterfaceContainerHelper*)(*iter).second;
490 : 78659 : ++iter;
491 : : }
492 [ + - ]: 1101264 : }
493 : : }
494 : :
495 : : // create a copy, because do not fire event in a guarded section
496 [ + + ]: 1179923 : for( t_type2ptr::size_type i = 0;
497 : : i < nSize; i++ )
498 : : {
499 [ + - ]: 78659 : if( ppListenerContainers[i] )
500 : 78659 : ppListenerContainers[i]->disposeAndClear( rEvt );
501 : : }
502 : :
503 [ + + ]: 1101264 : delete [] ppListenerContainers;
504 : 1101264 : }
505 : 0 : void OMultiTypeInterfaceContainerHelper::clear()
506 : : SAL_THROW(())
507 : : {
508 [ # # ]: 0 : ::osl::MutexGuard aGuard( rMutex );
509 : 0 : t_type2ptr * pMap = (t_type2ptr *)m_pMap;
510 : 0 : t_type2ptr::iterator iter = pMap->begin();
511 : 0 : t_type2ptr::iterator end = pMap->end();
512 : :
513 [ # # ][ # # ]: 0 : while( iter != end )
514 : : {
515 [ # # ]: 0 : ((OInterfaceContainerHelper*)(*iter).second)->clear();
516 : 0 : ++iter;
517 [ # # ]: 0 : }
518 : 0 : }
519 : :
520 : : // specialized class for long
521 : :
522 : : typedef ::std::vector< std::pair < sal_Int32 , void* > > t_long2ptr;
523 : :
524 : 49301 : static t_long2ptr::iterator findLong(t_long2ptr *pMap, sal_Int32 nKey )
525 : : {
526 : 49301 : t_long2ptr::iterator iter = pMap->begin();
527 : 49301 : t_long2ptr::iterator end = pMap->end();
528 : :
529 [ + - ][ + + ]: 239616 : while( iter != end )
530 : : {
531 [ + - ][ + + ]: 190315 : if (iter->first == nKey)
532 : 19849 : break;
533 [ + - ]: 170466 : ++iter;
534 : : }
535 : 49301 : return iter;
536 : : }
537 : :
538 : 238075 : OMultiTypeInterfaceContainerHelperInt32::OMultiTypeInterfaceContainerHelperInt32( Mutex & rMutex_ )
539 : : SAL_THROW(())
540 : : : m_pMap( NULL )
541 : 238075 : , rMutex( rMutex_ )
542 : : {
543 : : // delay pMap allocation until necessary.
544 : 238075 : }
545 : 234445 : OMultiTypeInterfaceContainerHelperInt32::~OMultiTypeInterfaceContainerHelperInt32()
546 : : SAL_THROW(())
547 : : {
548 [ + + ]: 234445 : if (!m_pMap)
549 : : return;
550 : :
551 : 2491 : t_long2ptr * pMap = (t_long2ptr *)m_pMap;
552 : 2491 : t_long2ptr::iterator iter = pMap->begin();
553 : 2491 : t_long2ptr::iterator end = pMap->end();
554 : :
555 [ + - ][ + + ]: 11943 : while( iter != end )
556 : : {
557 [ + - ][ + - ]: 9452 : delete (OInterfaceContainerHelper*)(*iter).second;
[ + - ]
558 [ + - ]: 9452 : (*iter).second = 0;
559 [ + - ]: 9452 : ++iter;
560 : : }
561 [ + - ]: 234445 : delete pMap;
562 : 234445 : }
563 : 0 : Sequence< sal_Int32 > OMultiTypeInterfaceContainerHelperInt32::getContainedTypes() const
564 : : SAL_THROW(())
565 : : {
566 : 0 : t_long2ptr * pMap = (t_long2ptr *)m_pMap;
567 : : t_long2ptr::size_type nSize;
568 : :
569 [ # # ]: 0 : ::osl::MutexGuard aGuard( rMutex );
570 [ # # ]: 0 : nSize = pMap ? pMap->size() : 0;
571 [ # # ]: 0 : if( nSize )
572 : : {
573 [ # # ]: 0 : ::com::sun::star::uno::Sequence< sal_Int32 > aInterfaceTypes( nSize );
574 [ # # ]: 0 : sal_Int32 * pArray = aInterfaceTypes.getArray();
575 : :
576 : 0 : t_long2ptr::iterator iter = pMap->begin();
577 : 0 : t_long2ptr::iterator end = pMap->end();
578 : :
579 : 0 : sal_Int32 i = 0;
580 [ # # ][ # # ]: 0 : while( iter != end )
581 : : {
582 : : // are interfaces added to this container?
583 [ # # ][ # # ]: 0 : if( ((OInterfaceContainerHelper*)(*iter).second)->getLength() )
[ # # ]
584 : : // yes, put the type in the array
585 [ # # ]: 0 : pArray[i++] = (*iter).first;
586 [ # # ]: 0 : ++iter;
587 : : }
588 [ # # ]: 0 : if( (t_long2ptr::size_type)i != nSize ) {
589 : : // may be empty container, reduce the sequence to the right size
590 [ # # ][ # # ]: 0 : aInterfaceTypes = ::com::sun::star::uno::Sequence< sal_Int32 >( pArray, i );
[ # # ]
591 : : }
592 [ # # ][ # # ]: 0 : return aInterfaceTypes;
593 : : }
594 [ # # ][ # # ]: 0 : return ::com::sun::star::uno::Sequence< sal_Int32 >();
595 : : }
596 : 56404 : OInterfaceContainerHelper * OMultiTypeInterfaceContainerHelperInt32::getContainer( const sal_Int32 & rKey ) const
597 : : SAL_THROW(())
598 : : {
599 [ + - ]: 56404 : ::osl::MutexGuard aGuard( rMutex );
600 : :
601 [ + + ]: 56404 : if (!m_pMap)
602 : 31139 : return 0;
603 : 25265 : t_long2ptr * pMap = (t_long2ptr *)m_pMap;
604 [ + - ]: 25265 : t_long2ptr::iterator iter = findLong( pMap, rKey );
605 [ + - ][ + + ]: 25265 : if( iter != pMap->end() )
606 [ + - ]: 5566 : return (OInterfaceContainerHelper*) (*iter).second;
607 [ + - ]: 56404 : return 0;
608 : : }
609 : 14893 : sal_Int32 OMultiTypeInterfaceContainerHelperInt32::addInterface(
610 : : const sal_Int32 & rKey, const Reference< XInterface > & rListener )
611 : : SAL_THROW(())
612 : : {
613 [ + - ]: 14893 : ::osl::MutexGuard aGuard( rMutex );
614 [ + + ]: 14893 : if (!m_pMap)
615 [ + - ][ + - ]: 2632 : m_pMap = new t_long2ptr();
616 : 14893 : t_long2ptr * pMap = (t_long2ptr *)m_pMap;
617 [ + - ]: 14893 : t_long2ptr::iterator iter = findLong( pMap, rKey );
618 [ + - ][ + + ]: 14893 : if( iter == pMap->end() )
619 : : {
620 [ + - ]: 9751 : OInterfaceContainerHelper * pLC = new OInterfaceContainerHelper( rMutex );
621 [ + - ][ + - ]: 9751 : pMap->push_back(std::pair< sal_Int32, void* >(rKey, pLC));
622 [ + - ]: 9751 : return pLC->addInterface( rListener );
623 : : }
624 : : else
625 [ + - ][ + - ]: 14893 : return ((OInterfaceContainerHelper*)(*iter).second)->addInterface( rListener );
[ + - ]
626 : : }
627 : 9143 : sal_Int32 OMultiTypeInterfaceContainerHelperInt32::removeInterface(
628 : : const sal_Int32 & rKey, const Reference< XInterface > & rListener )
629 : : SAL_THROW(())
630 : : {
631 [ + - ]: 9143 : ::osl::MutexGuard aGuard( rMutex );
632 : :
633 [ - + ]: 9143 : if (!m_pMap)
634 : 0 : return 0;
635 : : // search container with id nUik
636 : 9143 : t_long2ptr * pMap = (t_long2ptr *)m_pMap;
637 [ + - ]: 9143 : t_long2ptr::iterator iter = findLong( pMap, rKey );
638 : : // container found?
639 [ + - ][ + + ]: 9143 : if( iter != pMap->end() )
640 [ + - ][ + - ]: 9141 : return ((OInterfaceContainerHelper*)(*iter).second)->removeInterface( rListener );
641 : :
642 : : // no container with this id. Always return 0
643 [ + - ]: 9143 : return 0;
644 : : }
645 : 20996 : void OMultiTypeInterfaceContainerHelperInt32::disposeAndClear( const EventObject & rEvt )
646 : : SAL_THROW(())
647 : : {
648 : 20996 : t_long2ptr::size_type nSize = 0;
649 : 20996 : OInterfaceContainerHelper ** ppListenerContainers = NULL;
650 : : {
651 [ + - ]: 20996 : ::osl::MutexGuard aGuard( rMutex );
652 [ + + ]: 20996 : if (!m_pMap)
653 : 20996 : return;
654 : :
655 : 2380 : t_long2ptr * pMap = (t_long2ptr *)m_pMap;
656 : 2380 : nSize = pMap->size();
657 [ + - ]: 2380 : if( nSize )
658 : : {
659 : : typedef OInterfaceContainerHelper* ppp;
660 [ + - ]: 2380 : ppListenerContainers = new ppp[nSize];
661 : :
662 : 2380 : t_long2ptr::iterator iter = pMap->begin();
663 : 2380 : t_long2ptr::iterator end = pMap->end();
664 : :
665 : 2380 : t_long2ptr::size_type i = 0;
666 [ + - ][ + + ]: 10961 : while( iter != end )
667 : : {
668 [ + - ]: 8581 : ppListenerContainers[i++] = (OInterfaceContainerHelper*)(*iter).second;
669 [ + - ]: 8581 : ++iter;
670 : : }
671 [ + - ][ + + ]: 20996 : }
672 : : }
673 : :
674 : : // create a copy, because do not fire event in a guarded section
675 [ + + ]: 29577 : for( t_long2ptr::size_type i = 0;
676 : : i < nSize; i++ )
677 : : {
678 [ + - ]: 8581 : if( ppListenerContainers[i] )
679 : 8581 : ppListenerContainers[i]->disposeAndClear( rEvt );
680 : : }
681 : :
682 [ + - ]: 2380 : delete [] ppListenerContainers;
683 : : }
684 : 0 : void OMultiTypeInterfaceContainerHelperInt32::clear()
685 : : SAL_THROW(())
686 : : {
687 [ # # ]: 0 : ::osl::MutexGuard aGuard( rMutex );
688 [ # # ]: 0 : if (!m_pMap)
689 : 0 : return;
690 : 0 : t_long2ptr * pMap = (t_long2ptr *)m_pMap;
691 : 0 : t_long2ptr::iterator iter = pMap->begin();
692 : 0 : t_long2ptr::iterator end = pMap->end();
693 : :
694 [ # # ][ # # ]: 0 : while( iter != end )
695 : : {
696 [ # # ][ # # ]: 0 : ((OInterfaceContainerHelper*)(*iter).second)->clear();
697 [ # # ]: 0 : ++iter;
698 [ # # ][ # # ]: 0 : }
699 : : }
700 : :
701 : : }
702 : :
703 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|