xref: /trunk/main/cppuhelper/source/interfacecontainer.cxx (revision 883ba44fa57d8dd873f9491a44215c47fb8f7173)
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