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