1*9d7e27acSAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3*9d7e27acSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4*9d7e27acSAndrew Rist * or more contributor license agreements. See the NOTICE file
5*9d7e27acSAndrew Rist * distributed with this work for additional information
6*9d7e27acSAndrew Rist * regarding copyright ownership. The ASF licenses this file
7*9d7e27acSAndrew Rist * to you under the Apache License, Version 2.0 (the
8*9d7e27acSAndrew Rist * "License"); you may not use this file except in compliance
9*9d7e27acSAndrew Rist * with the License. You may obtain a copy of the License at
10*9d7e27acSAndrew Rist *
11*9d7e27acSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12*9d7e27acSAndrew Rist *
13*9d7e27acSAndrew Rist * Unless required by applicable law or agreed to in writing,
14*9d7e27acSAndrew Rist * software distributed under the License is distributed on an
15*9d7e27acSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*9d7e27acSAndrew Rist * KIND, either express or implied. See the License for the
17*9d7e27acSAndrew Rist * specific language governing permissions and limitations
18*9d7e27acSAndrew Rist * under the License.
19*9d7e27acSAndrew Rist *
20*9d7e27acSAndrew Rist *************************************************************/
21*9d7e27acSAndrew Rist
22*9d7e27acSAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_cppuhelper.hxx"
26cdf0e10cSrcweir
27cdf0e10cSrcweir #include <cppuhelper/interfacecontainer.hxx>
28cdf0e10cSrcweir #include <cppuhelper/queryinterface.hxx>
29cdf0e10cSrcweir #include <cppuhelper/propshlp.hxx>
30cdf0e10cSrcweir
31cdf0e10cSrcweir #include <osl/diagnose.h>
32cdf0e10cSrcweir #include <osl/mutex.hxx>
33cdf0e10cSrcweir
34cdf0e10cSrcweir #include <hash_map>
35cdf0e10cSrcweir
36cdf0e10cSrcweir #include <com/sun/star/lang/XEventListener.hpp>
37cdf0e10cSrcweir
38cdf0e10cSrcweir
39cdf0e10cSrcweir using namespace osl;
40cdf0e10cSrcweir using namespace com::sun::star::uno;
41cdf0e10cSrcweir using namespace com::sun::star::lang;
42cdf0e10cSrcweir
43cdf0e10cSrcweir namespace cppu
44cdf0e10cSrcweir {
45cdf0e10cSrcweir
46cdf0e10cSrcweir //===================================================================
47cdf0e10cSrcweir //===================================================================
48cdf0e10cSrcweir //===================================================================
49cdf0e10cSrcweir /**
50cdf0e10cSrcweir * Reallocate the sequence.
51cdf0e10cSrcweir */
realloc(Sequence<Reference<XInterface>> & rSeq,sal_Int32 nNewLen)52cdf0e10cSrcweir static void realloc( Sequence< Reference< XInterface > > & rSeq, sal_Int32 nNewLen )
53cdf0e10cSrcweir SAL_THROW( () )
54cdf0e10cSrcweir {
55cdf0e10cSrcweir rSeq.realloc( nNewLen );
56cdf0e10cSrcweir }
57cdf0e10cSrcweir
58cdf0e10cSrcweir /**
59cdf0e10cSrcweir * Remove an element from an interface sequence.
60cdf0e10cSrcweir */
sequenceRemoveElementAt(Sequence<Reference<XInterface>> & rSeq,sal_Int32 index)61cdf0e10cSrcweir static void sequenceRemoveElementAt( Sequence< Reference< XInterface > > & rSeq, sal_Int32 index )
62cdf0e10cSrcweir SAL_THROW( () )
63cdf0e10cSrcweir {
64cdf0e10cSrcweir sal_Int32 nNewLen = rSeq.getLength() - 1;
65cdf0e10cSrcweir
66cdf0e10cSrcweir Sequence< Reference< XInterface > > aDestSeq( rSeq.getLength() - 1 );
67cdf0e10cSrcweir // getArray on a const sequence is faster
68cdf0e10cSrcweir const Reference< XInterface > * pSource = ((const Sequence< Reference< XInterface > > &)rSeq).getConstArray();
69cdf0e10cSrcweir Reference< XInterface > * pDest = aDestSeq.getArray();
70cdf0e10cSrcweir sal_Int32 i = 0;
71cdf0e10cSrcweir for( ; i < index; i++ )
72cdf0e10cSrcweir pDest[i] = pSource[i];
73cdf0e10cSrcweir for( sal_Int32 j = i ; j < nNewLen; j++ )
74cdf0e10cSrcweir pDest[j] = pSource[j+1];
75cdf0e10cSrcweir rSeq = aDestSeq;
76cdf0e10cSrcweir }
77cdf0e10cSrcweir
78cdf0e10cSrcweir
79cdf0e10cSrcweir //-----------------------------------------------------------------------------
80cdf0e10cSrcweir //-----------------------------------------------------------------------------
81cdf0e10cSrcweir
82cdf0e10cSrcweir #ifdef _MSC_VER
83cdf0e10cSrcweir #pragma warning( disable: 4786 )
84cdf0e10cSrcweir #endif
85cdf0e10cSrcweir
86cdf0e10cSrcweir //===================================================================
87cdf0e10cSrcweir //===================================================================
88cdf0e10cSrcweir //===================================================================
OInterfaceIteratorHelper(OInterfaceContainerHelper & rCont_)89cdf0e10cSrcweir OInterfaceIteratorHelper::OInterfaceIteratorHelper( OInterfaceContainerHelper & rCont_ )
90cdf0e10cSrcweir SAL_THROW( () )
91cdf0e10cSrcweir : rCont( rCont_ )
92cdf0e10cSrcweir {
93cdf0e10cSrcweir MutexGuard aGuard( rCont.rMutex );
94cdf0e10cSrcweir if( rCont.bInUse )
95cdf0e10cSrcweir // worst case, two iterators at the same time
96cdf0e10cSrcweir rCont.copyAndResetInUse();
97cdf0e10cSrcweir bIsList = rCont_.bIsList;
98cdf0e10cSrcweir aData = rCont_.aData;
99cdf0e10cSrcweir if( bIsList )
100cdf0e10cSrcweir {
101cdf0e10cSrcweir rCont.bInUse = sal_True;
102cdf0e10cSrcweir nRemain = aData.pAsSequence->getLength();
103cdf0e10cSrcweir }
104cdf0e10cSrcweir else if( aData.pAsInterface )
105cdf0e10cSrcweir {
106cdf0e10cSrcweir aData.pAsInterface->acquire();
107cdf0e10cSrcweir nRemain = 1;
108cdf0e10cSrcweir }
109cdf0e10cSrcweir else
110cdf0e10cSrcweir nRemain = 0;
111cdf0e10cSrcweir }
112cdf0e10cSrcweir
~OInterfaceIteratorHelper()113cdf0e10cSrcweir OInterfaceIteratorHelper::~OInterfaceIteratorHelper() SAL_THROW( () )
114cdf0e10cSrcweir {
115cdf0e10cSrcweir sal_Bool bShared;
116cdf0e10cSrcweir {
117cdf0e10cSrcweir MutexGuard aGuard( rCont.rMutex );
118cdf0e10cSrcweir // bResetInUse protect the iterator against recursion
119cdf0e10cSrcweir bShared = aData.pAsSequence == rCont.aData.pAsSequence && rCont.bIsList;
120cdf0e10cSrcweir if( bShared )
121cdf0e10cSrcweir {
122cdf0e10cSrcweir OSL_ENSURE( rCont.bInUse, "OInterfaceContainerHelper must be in use" );
123cdf0e10cSrcweir rCont.bInUse = sal_False;
124cdf0e10cSrcweir }
125cdf0e10cSrcweir }
126cdf0e10cSrcweir
127cdf0e10cSrcweir if( !bShared )
128cdf0e10cSrcweir {
129cdf0e10cSrcweir if( bIsList )
130cdf0e10cSrcweir // Sequence owned by the iterator
131cdf0e10cSrcweir delete aData.pAsSequence;
132cdf0e10cSrcweir else if( aData.pAsInterface )
133cdf0e10cSrcweir // Interface is acquired by the iterator
134cdf0e10cSrcweir aData.pAsInterface->release();
135cdf0e10cSrcweir }
136cdf0e10cSrcweir }
137cdf0e10cSrcweir
next()138cdf0e10cSrcweir XInterface * OInterfaceIteratorHelper::next() SAL_THROW( () )
139cdf0e10cSrcweir {
140cdf0e10cSrcweir if( nRemain )
141cdf0e10cSrcweir {
142cdf0e10cSrcweir nRemain--;
143cdf0e10cSrcweir if( bIsList )
144cdf0e10cSrcweir // typecase to const,so the getArray method is faster
145cdf0e10cSrcweir return aData.pAsSequence->getConstArray()[nRemain].get();
146cdf0e10cSrcweir else if( aData.pAsInterface )
147cdf0e10cSrcweir return aData.pAsInterface;
148cdf0e10cSrcweir }
149cdf0e10cSrcweir // exception
150cdf0e10cSrcweir return 0;
151cdf0e10cSrcweir }
152cdf0e10cSrcweir
remove()153cdf0e10cSrcweir void OInterfaceIteratorHelper::remove() SAL_THROW( () )
154cdf0e10cSrcweir {
155cdf0e10cSrcweir if( bIsList )
156cdf0e10cSrcweir {
157cdf0e10cSrcweir OSL_ASSERT( nRemain >= 0 &&
158cdf0e10cSrcweir nRemain < aData.pAsSequence->getLength() );
159cdf0e10cSrcweir XInterface * p = aData.pAsSequence->getConstArray()[nRemain].get();
160cdf0e10cSrcweir rCont.removeInterface( * reinterpret_cast< const Reference< XInterface > * >( &p ) );
161cdf0e10cSrcweir }
162cdf0e10cSrcweir else
163cdf0e10cSrcweir {
164cdf0e10cSrcweir OSL_ASSERT( 0 == nRemain );
165cdf0e10cSrcweir rCont.removeInterface( * reinterpret_cast< const Reference< XInterface > * >(&aData.pAsInterface));
166cdf0e10cSrcweir }
167cdf0e10cSrcweir }
168cdf0e10cSrcweir
169cdf0e10cSrcweir //===================================================================
170cdf0e10cSrcweir //===================================================================
171cdf0e10cSrcweir //===================================================================
172cdf0e10cSrcweir
173cdf0e10cSrcweir
OInterfaceContainerHelper(Mutex & rMutex_)174cdf0e10cSrcweir OInterfaceContainerHelper::OInterfaceContainerHelper( Mutex & rMutex_ ) SAL_THROW( () )
175cdf0e10cSrcweir : rMutex( rMutex_ )
176cdf0e10cSrcweir , bInUse( sal_False )
177cdf0e10cSrcweir , bIsList( sal_False )
178cdf0e10cSrcweir {
179cdf0e10cSrcweir }
180cdf0e10cSrcweir
~OInterfaceContainerHelper()181cdf0e10cSrcweir OInterfaceContainerHelper::~OInterfaceContainerHelper() SAL_THROW( () )
182cdf0e10cSrcweir {
183cdf0e10cSrcweir OSL_ENSURE( !bInUse, "~OInterfaceContainerHelper but is in use" );
184cdf0e10cSrcweir if( bIsList )
185cdf0e10cSrcweir delete aData.pAsSequence;
186cdf0e10cSrcweir else if( aData.pAsInterface )
187cdf0e10cSrcweir aData.pAsInterface->release();
188cdf0e10cSrcweir }
189cdf0e10cSrcweir
getLength() const190cdf0e10cSrcweir sal_Int32 OInterfaceContainerHelper::getLength() const SAL_THROW( () )
191cdf0e10cSrcweir {
192cdf0e10cSrcweir MutexGuard aGuard( rMutex );
193cdf0e10cSrcweir if( bIsList )
194cdf0e10cSrcweir return aData.pAsSequence->getLength();
195cdf0e10cSrcweir else if( aData.pAsInterface )
196cdf0e10cSrcweir return 1;
197cdf0e10cSrcweir return 0;
198cdf0e10cSrcweir }
199cdf0e10cSrcweir
getElements() const200cdf0e10cSrcweir Sequence< Reference<XInterface> > OInterfaceContainerHelper::getElements() const SAL_THROW( () )
201cdf0e10cSrcweir {
202cdf0e10cSrcweir MutexGuard aGuard( rMutex );
203cdf0e10cSrcweir if( bIsList )
204cdf0e10cSrcweir return *aData.pAsSequence;
205cdf0e10cSrcweir else if( aData.pAsInterface )
206cdf0e10cSrcweir {
207cdf0e10cSrcweir Reference<XInterface> x( aData.pAsInterface );
208cdf0e10cSrcweir return Sequence< Reference< XInterface > >( &x, 1 );
209cdf0e10cSrcweir }
210cdf0e10cSrcweir return Sequence< Reference< XInterface > >();
211cdf0e10cSrcweir }
212cdf0e10cSrcweir
copyAndResetInUse()213cdf0e10cSrcweir void OInterfaceContainerHelper::copyAndResetInUse() SAL_THROW( () )
214cdf0e10cSrcweir {
215cdf0e10cSrcweir OSL_ENSURE( bInUse, "OInterfaceContainerHelper not in use" );
216cdf0e10cSrcweir if( bInUse )
217cdf0e10cSrcweir {
218cdf0e10cSrcweir // this should be the worst case. If a iterator is active
219cdf0e10cSrcweir // and a new Listener is added.
220cdf0e10cSrcweir if( bIsList )
221cdf0e10cSrcweir aData.pAsSequence = new Sequence< Reference< XInterface > >( *aData.pAsSequence );
222cdf0e10cSrcweir else if( aData.pAsInterface )
223cdf0e10cSrcweir aData.pAsInterface->acquire();
224cdf0e10cSrcweir
225cdf0e10cSrcweir bInUse = sal_False;
226cdf0e10cSrcweir }
227cdf0e10cSrcweir }
228cdf0e10cSrcweir
addInterface(const Reference<XInterface> & rListener)229cdf0e10cSrcweir sal_Int32 OInterfaceContainerHelper::addInterface( const Reference<XInterface> & rListener ) SAL_THROW( () )
230cdf0e10cSrcweir {
231cdf0e10cSrcweir OSL_ASSERT( rListener.is() );
232cdf0e10cSrcweir MutexGuard aGuard( rMutex );
233cdf0e10cSrcweir if( bInUse )
234cdf0e10cSrcweir copyAndResetInUse();
235cdf0e10cSrcweir
236cdf0e10cSrcweir if( bIsList )
237cdf0e10cSrcweir {
238cdf0e10cSrcweir sal_Int32 nLen = aData.pAsSequence->getLength();
239cdf0e10cSrcweir realloc( *aData.pAsSequence, nLen +1 );
240cdf0e10cSrcweir aData.pAsSequence->getArray()[ nLen ] = rListener;
241cdf0e10cSrcweir return nLen +1;
242cdf0e10cSrcweir }
243cdf0e10cSrcweir else if( aData.pAsInterface )
244cdf0e10cSrcweir {
245cdf0e10cSrcweir Sequence< Reference< XInterface > > * pSeq = new Sequence< Reference< XInterface > >( 2 );
246cdf0e10cSrcweir Reference<XInterface> * pArray = pSeq->getArray();
247cdf0e10cSrcweir pArray[0] = aData.pAsInterface;
248cdf0e10cSrcweir pArray[1] = rListener;
249cdf0e10cSrcweir aData.pAsInterface->release();
250cdf0e10cSrcweir aData.pAsSequence = pSeq;
251cdf0e10cSrcweir bIsList = sal_True;
252cdf0e10cSrcweir return 2;
253cdf0e10cSrcweir }
254cdf0e10cSrcweir else
255cdf0e10cSrcweir {
256cdf0e10cSrcweir aData.pAsInterface = rListener.get();
257cdf0e10cSrcweir if( rListener.is() )
258cdf0e10cSrcweir rListener->acquire();
259cdf0e10cSrcweir return 1;
260cdf0e10cSrcweir }
261cdf0e10cSrcweir }
262cdf0e10cSrcweir
removeInterface(const Reference<XInterface> & rListener)263cdf0e10cSrcweir sal_Int32 OInterfaceContainerHelper::removeInterface( const Reference<XInterface> & rListener ) SAL_THROW( () )
264cdf0e10cSrcweir {
265cdf0e10cSrcweir OSL_ASSERT( rListener.is() );
266cdf0e10cSrcweir MutexGuard aGuard( rMutex );
267cdf0e10cSrcweir if( bInUse )
268cdf0e10cSrcweir copyAndResetInUse();
269cdf0e10cSrcweir
270cdf0e10cSrcweir if( bIsList )
271cdf0e10cSrcweir {
272cdf0e10cSrcweir const Reference<XInterface> * pL = aData.pAsSequence->getConstArray();
273cdf0e10cSrcweir sal_Int32 nLen = aData.pAsSequence->getLength();
274cdf0e10cSrcweir sal_Int32 i;
275cdf0e10cSrcweir for( i = 0; i < nLen; i++ )
276cdf0e10cSrcweir {
277cdf0e10cSrcweir // It is not valid to compare the Pointer direkt, but is is is much
278cdf0e10cSrcweir // more faster.
279cdf0e10cSrcweir if( pL[i].get() == rListener.get() )
280cdf0e10cSrcweir {
281cdf0e10cSrcweir sequenceRemoveElementAt( *aData.pAsSequence, i );
282cdf0e10cSrcweir break;
283cdf0e10cSrcweir }
284cdf0e10cSrcweir }
285cdf0e10cSrcweir
286cdf0e10cSrcweir if( i == nLen )
287cdf0e10cSrcweir {
288cdf0e10cSrcweir // interface not found, use the correct compare method
289cdf0e10cSrcweir for( i = 0; i < nLen; i++ )
290cdf0e10cSrcweir {
291cdf0e10cSrcweir if( pL[i] == rListener )
292cdf0e10cSrcweir {
293cdf0e10cSrcweir sequenceRemoveElementAt(*aData.pAsSequence, i );
294cdf0e10cSrcweir break;
295cdf0e10cSrcweir }
296cdf0e10cSrcweir }
297cdf0e10cSrcweir }
298cdf0e10cSrcweir
299cdf0e10cSrcweir if( aData.pAsSequence->getLength() == 1 )
300cdf0e10cSrcweir {
301cdf0e10cSrcweir XInterface * p = aData.pAsSequence->getConstArray()[0].get();
302cdf0e10cSrcweir p->acquire();
303cdf0e10cSrcweir delete aData.pAsSequence;
304cdf0e10cSrcweir aData.pAsInterface = p;
305cdf0e10cSrcweir bIsList = sal_False;
306cdf0e10cSrcweir return 1;
307cdf0e10cSrcweir }
308cdf0e10cSrcweir else
309cdf0e10cSrcweir return aData.pAsSequence->getLength();
310cdf0e10cSrcweir }
311cdf0e10cSrcweir else if( aData.pAsInterface && Reference<XInterface>( aData.pAsInterface ) == rListener )
312cdf0e10cSrcweir {
313cdf0e10cSrcweir aData.pAsInterface->release();
314cdf0e10cSrcweir aData.pAsInterface = 0;
315cdf0e10cSrcweir }
316cdf0e10cSrcweir return aData.pAsInterface ? 1 : 0;
317cdf0e10cSrcweir }
318cdf0e10cSrcweir
disposeAndClear(const EventObject & rEvt)319cdf0e10cSrcweir void OInterfaceContainerHelper::disposeAndClear( const EventObject & rEvt ) SAL_THROW( () )
320cdf0e10cSrcweir {
321cdf0e10cSrcweir ClearableMutexGuard aGuard( rMutex );
322cdf0e10cSrcweir OInterfaceIteratorHelper aIt( *this );
323cdf0e10cSrcweir // Container freigeben, falls im disposing neue Eintr�ge kommen
324cdf0e10cSrcweir OSL_ENSURE( !bIsList || bInUse, "OInterfaceContainerHelper not in use" );
325cdf0e10cSrcweir if( !bIsList && aData.pAsInterface )
326cdf0e10cSrcweir aData.pAsInterface->release();
327cdf0e10cSrcweir // set the member to null, the iterator delete the values
328cdf0e10cSrcweir aData.pAsInterface = NULL;
329cdf0e10cSrcweir bIsList = sal_False;
330cdf0e10cSrcweir bInUse = sal_False;
331cdf0e10cSrcweir aGuard.clear();
332cdf0e10cSrcweir while( aIt.hasMoreElements() )
333cdf0e10cSrcweir {
334cdf0e10cSrcweir try
335cdf0e10cSrcweir {
336cdf0e10cSrcweir Reference<XEventListener > xLst( aIt.next(), UNO_QUERY );
337cdf0e10cSrcweir if( xLst.is() )
338cdf0e10cSrcweir xLst->disposing( rEvt );
339cdf0e10cSrcweir }
340cdf0e10cSrcweir catch ( RuntimeException & )
341cdf0e10cSrcweir {
342cdf0e10cSrcweir // be robust, if e.g. a remote bridge has disposed already.
343cdf0e10cSrcweir // there is no way, to delegate the error to the caller :o(.
344cdf0e10cSrcweir }
345cdf0e10cSrcweir }
346cdf0e10cSrcweir }
347cdf0e10cSrcweir
348cdf0e10cSrcweir
clear()349cdf0e10cSrcweir void OInterfaceContainerHelper::clear() SAL_THROW( () )
350cdf0e10cSrcweir {
351cdf0e10cSrcweir ClearableMutexGuard aGuard( rMutex );
352cdf0e10cSrcweir OInterfaceIteratorHelper aIt( *this );
353cdf0e10cSrcweir // Container freigeben, falls im disposing neue Eintr�ge kommen
354cdf0e10cSrcweir OSL_ENSURE( !bIsList || bInUse, "OInterfaceContainerHelper not in use" );
355cdf0e10cSrcweir if( !bIsList && aData.pAsInterface )
356cdf0e10cSrcweir aData.pAsInterface->release();
357cdf0e10cSrcweir // set the member to null, the iterator delete the values
358cdf0e10cSrcweir aData.pAsInterface = 0;
359cdf0e10cSrcweir bIsList = sal_False;
360cdf0e10cSrcweir bInUse = sal_False;
361cdf0e10cSrcweir // release mutex before aIt destructor call
362cdf0e10cSrcweir aGuard.clear();
363cdf0e10cSrcweir }
364cdf0e10cSrcweir
365cdf0e10cSrcweir //##################################################################################################
366cdf0e10cSrcweir //##################################################################################################
367cdf0e10cSrcweir //##################################################################################################
368cdf0e10cSrcweir
369cdf0e10cSrcweir // specialized class for type
370cdf0e10cSrcweir
371cdf0e10cSrcweir typedef ::std::vector< std::pair < Type , void* > > t_type2ptr;
372cdf0e10cSrcweir
OMultiTypeInterfaceContainerHelper(Mutex & rMutex_)373cdf0e10cSrcweir OMultiTypeInterfaceContainerHelper::OMultiTypeInterfaceContainerHelper( Mutex & rMutex_ )
374cdf0e10cSrcweir SAL_THROW( () )
375cdf0e10cSrcweir : rMutex( rMutex_ )
376cdf0e10cSrcweir {
377cdf0e10cSrcweir m_pMap = new t_type2ptr();
378cdf0e10cSrcweir }
~OMultiTypeInterfaceContainerHelper()379cdf0e10cSrcweir OMultiTypeInterfaceContainerHelper::~OMultiTypeInterfaceContainerHelper()
380cdf0e10cSrcweir SAL_THROW( () )
381cdf0e10cSrcweir {
382cdf0e10cSrcweir t_type2ptr * pMap = (t_type2ptr *)m_pMap;
383cdf0e10cSrcweir t_type2ptr::iterator iter = pMap->begin();
384cdf0e10cSrcweir t_type2ptr::iterator end = pMap->end();
385cdf0e10cSrcweir
386cdf0e10cSrcweir while( iter != end )
387cdf0e10cSrcweir {
388cdf0e10cSrcweir delete (OInterfaceContainerHelper*)(*iter).second;
389cdf0e10cSrcweir (*iter).second = 0;
390cdf0e10cSrcweir ++iter;
391cdf0e10cSrcweir }
392cdf0e10cSrcweir delete pMap;
393cdf0e10cSrcweir }
getContainedTypes() const394cdf0e10cSrcweir Sequence< Type > OMultiTypeInterfaceContainerHelper::getContainedTypes() const
395cdf0e10cSrcweir SAL_THROW( () )
396cdf0e10cSrcweir {
397cdf0e10cSrcweir t_type2ptr * pMap = (t_type2ptr *)m_pMap;
398cdf0e10cSrcweir t_type2ptr::size_type nSize;
399cdf0e10cSrcweir
400cdf0e10cSrcweir ::osl::MutexGuard aGuard( rMutex );
401cdf0e10cSrcweir nSize = pMap->size();
402cdf0e10cSrcweir if( nSize )
403cdf0e10cSrcweir {
404cdf0e10cSrcweir ::com::sun::star::uno::Sequence< Type > aInterfaceTypes( nSize );
405cdf0e10cSrcweir Type * pArray = aInterfaceTypes.getArray();
406cdf0e10cSrcweir
407cdf0e10cSrcweir t_type2ptr::iterator iter = pMap->begin();
408cdf0e10cSrcweir t_type2ptr::iterator end = pMap->end();
409cdf0e10cSrcweir
410cdf0e10cSrcweir sal_Int32 i = 0;
411cdf0e10cSrcweir while( iter != end )
412cdf0e10cSrcweir {
413cdf0e10cSrcweir // are interfaces added to this container?
414cdf0e10cSrcweir if( ((OInterfaceContainerHelper*)(*iter).second)->getLength() )
415cdf0e10cSrcweir // yes, put the type in the array
416cdf0e10cSrcweir pArray[i++] = (*iter).first;
417cdf0e10cSrcweir ++iter;
418cdf0e10cSrcweir }
419cdf0e10cSrcweir if( (t_type2ptr::size_type)i != nSize ) {
420cdf0e10cSrcweir // may be empty container, reduce the sequence to the right size
421cdf0e10cSrcweir aInterfaceTypes = ::com::sun::star::uno::Sequence< Type >( pArray, i );
422cdf0e10cSrcweir }
423cdf0e10cSrcweir return aInterfaceTypes;
424cdf0e10cSrcweir }
425cdf0e10cSrcweir return ::com::sun::star::uno::Sequence< Type >();
426cdf0e10cSrcweir }
427cdf0e10cSrcweir
findType(t_type2ptr * pMap,const Type & rKey)428cdf0e10cSrcweir static t_type2ptr::iterator findType(t_type2ptr *pMap, const Type & rKey )
429cdf0e10cSrcweir {
430cdf0e10cSrcweir t_type2ptr::iterator iter = pMap->begin();
431cdf0e10cSrcweir t_type2ptr::iterator end = pMap->end();
432cdf0e10cSrcweir
433cdf0e10cSrcweir while( iter != end )
434cdf0e10cSrcweir {
435cdf0e10cSrcweir if (iter->first == rKey)
436cdf0e10cSrcweir break;
437cdf0e10cSrcweir iter++;
438cdf0e10cSrcweir }
439cdf0e10cSrcweir return iter;
440cdf0e10cSrcweir }
441cdf0e10cSrcweir
getContainer(const Type & rKey) const442cdf0e10cSrcweir OInterfaceContainerHelper * OMultiTypeInterfaceContainerHelper::getContainer( const Type & rKey ) const
443cdf0e10cSrcweir SAL_THROW( () )
444cdf0e10cSrcweir {
445cdf0e10cSrcweir ::osl::MutexGuard aGuard( rMutex );
446cdf0e10cSrcweir
447cdf0e10cSrcweir t_type2ptr * pMap = (t_type2ptr *)m_pMap;
448cdf0e10cSrcweir t_type2ptr::iterator iter = findType( pMap, rKey );
449cdf0e10cSrcweir if( iter != pMap->end() )
450cdf0e10cSrcweir return (OInterfaceContainerHelper*) (*iter).second;
451cdf0e10cSrcweir return 0;
452cdf0e10cSrcweir }
addInterface(const Type & rKey,const Reference<XInterface> & rListener)453cdf0e10cSrcweir sal_Int32 OMultiTypeInterfaceContainerHelper::addInterface(
454cdf0e10cSrcweir const Type & rKey, const Reference< XInterface > & rListener )
455cdf0e10cSrcweir SAL_THROW( () )
456cdf0e10cSrcweir {
457cdf0e10cSrcweir ::osl::MutexGuard aGuard( rMutex );
458cdf0e10cSrcweir t_type2ptr * pMap = (t_type2ptr *)m_pMap;
459cdf0e10cSrcweir t_type2ptr::iterator iter = findType( pMap, rKey );
460cdf0e10cSrcweir if( iter == pMap->end() )
461cdf0e10cSrcweir {
462cdf0e10cSrcweir OInterfaceContainerHelper * pLC = new OInterfaceContainerHelper( rMutex );
463cdf0e10cSrcweir pMap->push_back(std::pair<Type, void*>(rKey, pLC));
464cdf0e10cSrcweir return pLC->addInterface( rListener );
465cdf0e10cSrcweir }
466cdf0e10cSrcweir else
467cdf0e10cSrcweir return ((OInterfaceContainerHelper*)(*iter).second)->addInterface( rListener );
468cdf0e10cSrcweir }
removeInterface(const Type & rKey,const Reference<XInterface> & rListener)469cdf0e10cSrcweir sal_Int32 OMultiTypeInterfaceContainerHelper::removeInterface(
470cdf0e10cSrcweir const Type & rKey, const Reference< XInterface > & rListener )
471cdf0e10cSrcweir SAL_THROW( () )
472cdf0e10cSrcweir {
473cdf0e10cSrcweir ::osl::MutexGuard aGuard( rMutex );
474cdf0e10cSrcweir
475cdf0e10cSrcweir // search container with id nUik
476cdf0e10cSrcweir t_type2ptr * pMap = (t_type2ptr *)m_pMap;
477cdf0e10cSrcweir t_type2ptr::iterator iter = findType( pMap, rKey );
478cdf0e10cSrcweir // container found?
479cdf0e10cSrcweir if( iter != pMap->end() )
480cdf0e10cSrcweir return ((OInterfaceContainerHelper*)(*iter).second)->removeInterface( rListener );
481cdf0e10cSrcweir
482cdf0e10cSrcweir // no container with this id. Always return 0
483cdf0e10cSrcweir return 0;
484cdf0e10cSrcweir }
disposeAndClear(const EventObject & rEvt)485cdf0e10cSrcweir void OMultiTypeInterfaceContainerHelper::disposeAndClear( const EventObject & rEvt )
486cdf0e10cSrcweir SAL_THROW( () )
487cdf0e10cSrcweir {
488cdf0e10cSrcweir t_type2ptr::size_type nSize = 0;
489cdf0e10cSrcweir OInterfaceContainerHelper ** ppListenerContainers = NULL;
490cdf0e10cSrcweir {
491cdf0e10cSrcweir ::osl::MutexGuard aGuard( rMutex );
492cdf0e10cSrcweir t_type2ptr * pMap = (t_type2ptr *)m_pMap;
493cdf0e10cSrcweir nSize = pMap->size();
494cdf0e10cSrcweir if( nSize )
495cdf0e10cSrcweir {
496cdf0e10cSrcweir typedef OInterfaceContainerHelper* ppp;
497cdf0e10cSrcweir ppListenerContainers = new ppp[nSize];
498cdf0e10cSrcweir //ppListenerContainers = new (ListenerContainer*)[nSize];
499cdf0e10cSrcweir
500cdf0e10cSrcweir t_type2ptr::iterator iter = pMap->begin();
501cdf0e10cSrcweir t_type2ptr::iterator end = pMap->end();
502cdf0e10cSrcweir
503cdf0e10cSrcweir t_type2ptr::size_type i = 0;
504cdf0e10cSrcweir while( iter != end )
505cdf0e10cSrcweir {
506cdf0e10cSrcweir ppListenerContainers[i++] = (OInterfaceContainerHelper*)(*iter).second;
507cdf0e10cSrcweir ++iter;
508cdf0e10cSrcweir }
509cdf0e10cSrcweir }
510cdf0e10cSrcweir }
511cdf0e10cSrcweir
512cdf0e10cSrcweir // create a copy, because do not fire event in a guarded section
513cdf0e10cSrcweir for( t_type2ptr::size_type i = 0;
514cdf0e10cSrcweir i < nSize; i++ )
515cdf0e10cSrcweir {
516cdf0e10cSrcweir if( ppListenerContainers[i] )
517cdf0e10cSrcweir ppListenerContainers[i]->disposeAndClear( rEvt );
518cdf0e10cSrcweir }
519cdf0e10cSrcweir
520cdf0e10cSrcweir delete [] ppListenerContainers;
521cdf0e10cSrcweir }
clear()522cdf0e10cSrcweir void OMultiTypeInterfaceContainerHelper::clear()
523cdf0e10cSrcweir SAL_THROW( () )
524cdf0e10cSrcweir {
525cdf0e10cSrcweir ::osl::MutexGuard aGuard( rMutex );
526cdf0e10cSrcweir t_type2ptr * pMap = (t_type2ptr *)m_pMap;
527cdf0e10cSrcweir t_type2ptr::iterator iter = pMap->begin();
528cdf0e10cSrcweir t_type2ptr::iterator end = pMap->end();
529cdf0e10cSrcweir
530cdf0e10cSrcweir while( iter != end )
531cdf0e10cSrcweir {
532cdf0e10cSrcweir ((OInterfaceContainerHelper*)(*iter).second)->clear();
533cdf0e10cSrcweir ++iter;
534cdf0e10cSrcweir }
535cdf0e10cSrcweir }
536cdf0e10cSrcweir
537cdf0e10cSrcweir
538cdf0e10cSrcweir //##################################################################################################
539cdf0e10cSrcweir //##################################################################################################
540cdf0e10cSrcweir //##################################################################################################
541cdf0e10cSrcweir
542cdf0e10cSrcweir // specialized class for long
543cdf0e10cSrcweir
544cdf0e10cSrcweir typedef ::std::vector< std::pair < sal_Int32 , void* > > t_long2ptr;
545cdf0e10cSrcweir
findLong(t_long2ptr * pMap,sal_Int32 nKey)546cdf0e10cSrcweir static t_long2ptr::iterator findLong(t_long2ptr *pMap, sal_Int32 nKey )
547cdf0e10cSrcweir {
548cdf0e10cSrcweir t_long2ptr::iterator iter = pMap->begin();
549cdf0e10cSrcweir t_long2ptr::iterator end = pMap->end();
550cdf0e10cSrcweir
551cdf0e10cSrcweir while( iter != end )
552cdf0e10cSrcweir {
553cdf0e10cSrcweir if (iter->first == nKey)
554cdf0e10cSrcweir break;
555cdf0e10cSrcweir iter++;
556cdf0e10cSrcweir }
557cdf0e10cSrcweir return iter;
558cdf0e10cSrcweir }
559cdf0e10cSrcweir
OMultiTypeInterfaceContainerHelperInt32(Mutex & rMutex_)560cdf0e10cSrcweir OMultiTypeInterfaceContainerHelperInt32::OMultiTypeInterfaceContainerHelperInt32( Mutex & rMutex_ )
561cdf0e10cSrcweir SAL_THROW( () )
562cdf0e10cSrcweir : m_pMap( NULL )
563cdf0e10cSrcweir , rMutex( rMutex_ )
564cdf0e10cSrcweir {
565cdf0e10cSrcweir // delay pMap allocation until necessary.
566cdf0e10cSrcweir }
~OMultiTypeInterfaceContainerHelperInt32()567cdf0e10cSrcweir OMultiTypeInterfaceContainerHelperInt32::~OMultiTypeInterfaceContainerHelperInt32()
568cdf0e10cSrcweir SAL_THROW( () )
569cdf0e10cSrcweir {
570cdf0e10cSrcweir if (!m_pMap)
571cdf0e10cSrcweir return;
572cdf0e10cSrcweir
573cdf0e10cSrcweir t_long2ptr * pMap = (t_long2ptr *)m_pMap;
574cdf0e10cSrcweir t_long2ptr::iterator iter = pMap->begin();
575cdf0e10cSrcweir t_long2ptr::iterator end = pMap->end();
576cdf0e10cSrcweir
577cdf0e10cSrcweir while( iter != end )
578cdf0e10cSrcweir {
579cdf0e10cSrcweir delete (OInterfaceContainerHelper*)(*iter).second;
580cdf0e10cSrcweir (*iter).second = 0;
581cdf0e10cSrcweir ++iter;
582cdf0e10cSrcweir }
583cdf0e10cSrcweir delete pMap;
584cdf0e10cSrcweir }
getContainedTypes() const585cdf0e10cSrcweir Sequence< sal_Int32 > OMultiTypeInterfaceContainerHelperInt32::getContainedTypes() const
586cdf0e10cSrcweir SAL_THROW( () )
587cdf0e10cSrcweir {
588cdf0e10cSrcweir t_long2ptr * pMap = (t_long2ptr *)m_pMap;
589cdf0e10cSrcweir t_long2ptr::size_type nSize;
590cdf0e10cSrcweir
591cdf0e10cSrcweir ::osl::MutexGuard aGuard( rMutex );
592cdf0e10cSrcweir nSize = pMap ? pMap->size() : 0;
593cdf0e10cSrcweir if( nSize )
594cdf0e10cSrcweir {
595cdf0e10cSrcweir ::com::sun::star::uno::Sequence< sal_Int32 > aInterfaceTypes( nSize );
596cdf0e10cSrcweir sal_Int32 * pArray = aInterfaceTypes.getArray();
597cdf0e10cSrcweir
598cdf0e10cSrcweir t_long2ptr::iterator iter = pMap->begin();
599cdf0e10cSrcweir t_long2ptr::iterator end = pMap->end();
600cdf0e10cSrcweir
601cdf0e10cSrcweir sal_Int32 i = 0;
602cdf0e10cSrcweir while( iter != end )
603cdf0e10cSrcweir {
604cdf0e10cSrcweir // are interfaces added to this container?
605cdf0e10cSrcweir if( ((OInterfaceContainerHelper*)(*iter).second)->getLength() )
606cdf0e10cSrcweir // yes, put the type in the array
607cdf0e10cSrcweir pArray[i++] = (*iter).first;
608cdf0e10cSrcweir ++iter;
609cdf0e10cSrcweir }
610cdf0e10cSrcweir if( (t_long2ptr::size_type)i != nSize ) {
611cdf0e10cSrcweir // may be empty container, reduce the sequence to the right size
612cdf0e10cSrcweir aInterfaceTypes = ::com::sun::star::uno::Sequence< sal_Int32 >( pArray, i );
613cdf0e10cSrcweir }
614cdf0e10cSrcweir return aInterfaceTypes;
615cdf0e10cSrcweir }
616cdf0e10cSrcweir return ::com::sun::star::uno::Sequence< sal_Int32 >();
617cdf0e10cSrcweir }
getContainer(const sal_Int32 & rKey) const618cdf0e10cSrcweir OInterfaceContainerHelper * OMultiTypeInterfaceContainerHelperInt32::getContainer( const sal_Int32 & rKey ) const
619cdf0e10cSrcweir SAL_THROW( () )
620cdf0e10cSrcweir {
621cdf0e10cSrcweir ::osl::MutexGuard aGuard( rMutex );
622cdf0e10cSrcweir
623cdf0e10cSrcweir if (!m_pMap)
624cdf0e10cSrcweir return 0;
625cdf0e10cSrcweir t_long2ptr * pMap = (t_long2ptr *)m_pMap;
626cdf0e10cSrcweir t_long2ptr::iterator iter = findLong( pMap, rKey );
627cdf0e10cSrcweir if( iter != pMap->end() )
628cdf0e10cSrcweir return (OInterfaceContainerHelper*) (*iter).second;
629cdf0e10cSrcweir return 0;
630cdf0e10cSrcweir }
addInterface(const sal_Int32 & rKey,const Reference<XInterface> & rListener)631cdf0e10cSrcweir sal_Int32 OMultiTypeInterfaceContainerHelperInt32::addInterface(
632cdf0e10cSrcweir const sal_Int32 & rKey, const Reference< XInterface > & rListener )
633cdf0e10cSrcweir SAL_THROW( () )
634cdf0e10cSrcweir {
635cdf0e10cSrcweir ::osl::MutexGuard aGuard( rMutex );
636cdf0e10cSrcweir if (!m_pMap)
637cdf0e10cSrcweir m_pMap = new t_long2ptr();
638cdf0e10cSrcweir t_long2ptr * pMap = (t_long2ptr *)m_pMap;
639cdf0e10cSrcweir t_long2ptr::iterator iter = findLong( pMap, rKey );
640cdf0e10cSrcweir if( iter == pMap->end() )
641cdf0e10cSrcweir {
642cdf0e10cSrcweir OInterfaceContainerHelper * pLC = new OInterfaceContainerHelper( rMutex );
643cdf0e10cSrcweir pMap->push_back(std::pair< sal_Int32, void* >(rKey, pLC));
644cdf0e10cSrcweir return pLC->addInterface( rListener );
645cdf0e10cSrcweir }
646cdf0e10cSrcweir else
647cdf0e10cSrcweir return ((OInterfaceContainerHelper*)(*iter).second)->addInterface( rListener );
648cdf0e10cSrcweir }
removeInterface(const sal_Int32 & rKey,const Reference<XInterface> & rListener)649cdf0e10cSrcweir sal_Int32 OMultiTypeInterfaceContainerHelperInt32::removeInterface(
650cdf0e10cSrcweir const sal_Int32 & rKey, const Reference< XInterface > & rListener )
651cdf0e10cSrcweir SAL_THROW( () )
652cdf0e10cSrcweir {
653cdf0e10cSrcweir ::osl::MutexGuard aGuard( rMutex );
654cdf0e10cSrcweir
655cdf0e10cSrcweir if (!m_pMap)
656cdf0e10cSrcweir return 0;
657cdf0e10cSrcweir // search container with id nUik
658cdf0e10cSrcweir t_long2ptr * pMap = (t_long2ptr *)m_pMap;
659cdf0e10cSrcweir t_long2ptr::iterator iter = findLong( pMap, rKey );
660cdf0e10cSrcweir // container found?
661cdf0e10cSrcweir if( iter != pMap->end() )
662cdf0e10cSrcweir return ((OInterfaceContainerHelper*)(*iter).second)->removeInterface( rListener );
663cdf0e10cSrcweir
664cdf0e10cSrcweir // no container with this id. Always return 0
665cdf0e10cSrcweir return 0;
666cdf0e10cSrcweir }
disposeAndClear(const EventObject & rEvt)667cdf0e10cSrcweir void OMultiTypeInterfaceContainerHelperInt32::disposeAndClear( const EventObject & rEvt )
668cdf0e10cSrcweir SAL_THROW( () )
669cdf0e10cSrcweir {
670cdf0e10cSrcweir t_long2ptr::size_type nSize = 0;
671cdf0e10cSrcweir OInterfaceContainerHelper ** ppListenerContainers = NULL;
672cdf0e10cSrcweir {
673cdf0e10cSrcweir ::osl::MutexGuard aGuard( rMutex );
674cdf0e10cSrcweir if (!m_pMap)
675cdf0e10cSrcweir return;
676cdf0e10cSrcweir
677cdf0e10cSrcweir t_long2ptr * pMap = (t_long2ptr *)m_pMap;
678cdf0e10cSrcweir nSize = pMap->size();
679cdf0e10cSrcweir if( nSize )
680cdf0e10cSrcweir {
681cdf0e10cSrcweir typedef OInterfaceContainerHelper* ppp;
682cdf0e10cSrcweir ppListenerContainers = new ppp[nSize];
683cdf0e10cSrcweir //ppListenerContainers = new (ListenerContainer*)[nSize];
684cdf0e10cSrcweir
685cdf0e10cSrcweir t_long2ptr::iterator iter = pMap->begin();
686cdf0e10cSrcweir t_long2ptr::iterator end = pMap->end();
687cdf0e10cSrcweir
688cdf0e10cSrcweir t_long2ptr::size_type i = 0;
689cdf0e10cSrcweir while( iter != end )
690cdf0e10cSrcweir {
691cdf0e10cSrcweir ppListenerContainers[i++] = (OInterfaceContainerHelper*)(*iter).second;
692cdf0e10cSrcweir ++iter;
693cdf0e10cSrcweir }
694cdf0e10cSrcweir }
695cdf0e10cSrcweir }
696cdf0e10cSrcweir
697cdf0e10cSrcweir // create a copy, because do not fire event in a guarded section
698cdf0e10cSrcweir for( t_long2ptr::size_type i = 0;
699cdf0e10cSrcweir i < nSize; i++ )
700cdf0e10cSrcweir {
701cdf0e10cSrcweir if( ppListenerContainers[i] )
702cdf0e10cSrcweir ppListenerContainers[i]->disposeAndClear( rEvt );
703cdf0e10cSrcweir }
704cdf0e10cSrcweir
705cdf0e10cSrcweir delete [] ppListenerContainers;
706cdf0e10cSrcweir }
clear()707cdf0e10cSrcweir void OMultiTypeInterfaceContainerHelperInt32::clear()
708cdf0e10cSrcweir SAL_THROW( () )
709cdf0e10cSrcweir {
710cdf0e10cSrcweir ::osl::MutexGuard aGuard( rMutex );
711cdf0e10cSrcweir if (!m_pMap)
712cdf0e10cSrcweir return;
713cdf0e10cSrcweir t_long2ptr * pMap = (t_long2ptr *)m_pMap;
714cdf0e10cSrcweir t_long2ptr::iterator iter = pMap->begin();
715cdf0e10cSrcweir t_long2ptr::iterator end = pMap->end();
716cdf0e10cSrcweir
717cdf0e10cSrcweir while( iter != end )
718cdf0e10cSrcweir {
719cdf0e10cSrcweir ((OInterfaceContainerHelper*)(*iter).second)->clear();
720cdf0e10cSrcweir ++iter;
721cdf0e10cSrcweir }
722cdf0e10cSrcweir }
723cdf0e10cSrcweir
724cdf0e10cSrcweir }
725cdf0e10cSrcweir
726