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