12123d757SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
32123d757SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
42123d757SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
52123d757SAndrew Rist  * distributed with this work for additional information
62123d757SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
72123d757SAndrew Rist  * to you under the Apache License, Version 2.0 (the
82123d757SAndrew Rist  * "License"); you may not use this file except in compliance
92123d757SAndrew Rist  * with the License.  You may obtain a copy of the License at
102123d757SAndrew Rist  *
112123d757SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
122123d757SAndrew Rist  *
132123d757SAndrew Rist  * Unless required by applicable law or agreed to in writing,
142123d757SAndrew Rist  * software distributed under the License is distributed on an
152123d757SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
162123d757SAndrew Rist  * KIND, either express or implied.  See the License for the
172123d757SAndrew Rist  * specific language governing permissions and limitations
182123d757SAndrew Rist  * under the License.
192123d757SAndrew Rist  *
202123d757SAndrew Rist  *************************************************************/
212123d757SAndrew Rist 
222123d757SAndrew Rist 
23cdf0e10cSrcweir #ifndef _CPPUHELPER_INTERFACECONTAINER_H_
24cdf0e10cSrcweir #define _CPPUHELPER_INTERFACECONTAINER_H_
25cdf0e10cSrcweir 
26cdf0e10cSrcweir #include <vector>
27cdf0e10cSrcweir #include <osl/mutex.hxx>
28cdf0e10cSrcweir #include <rtl/alloc.h>
29cdf0e10cSrcweir #include <com/sun/star/uno/Sequence.hxx>
30cdf0e10cSrcweir #include <com/sun/star/uno/XInterface.hpp>
31cdf0e10cSrcweir #ifndef _COM_SUN_STAR_LANG_EVENTOBJECT_HXX_
32cdf0e10cSrcweir #include <com/sun/star/lang/EventObject.hpp>
33cdf0e10cSrcweir #endif
34cdf0e10cSrcweir 
35cdf0e10cSrcweir #ifndef _COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HXX_
36cdf0e10cSrcweir #include "com/sun/star/lang/DisposedException.hpp"
37cdf0e10cSrcweir #endif
38cdf0e10cSrcweir 
39*ebbaf3b8SDamjan Jovanovic #include "cppuhelper/cppuhelperdllapi.h"
40*ebbaf3b8SDamjan Jovanovic 
41cdf0e10cSrcweir /** */ //for docpp
42cdf0e10cSrcweir namespace cppu
43cdf0e10cSrcweir {
44cdf0e10cSrcweir 
45cdf0e10cSrcweir namespace detail {
46cdf0e10cSrcweir 
47cdf0e10cSrcweir     union element_alias
48cdf0e10cSrcweir     {
49cdf0e10cSrcweir         ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > > *pAsSequence;
50cdf0e10cSrcweir         ::com::sun::star::uno::XInterface * pAsInterface;
element_alias()51cdf0e10cSrcweir         element_alias() : pAsInterface(0) {}
52cdf0e10cSrcweir     };
53cdf0e10cSrcweir 
54cdf0e10cSrcweir }
55cdf0e10cSrcweir 
56cdf0e10cSrcweir //===================================================================
57cdf0e10cSrcweir class OInterfaceContainerHelper;
58cdf0e10cSrcweir /**
59cdf0e10cSrcweir   This is the iterator of a InterfaceContainerHelper. Typically
60cdf0e10cSrcweir   one constructs an instance on the stack for one firing session.
61cdf0e10cSrcweir   It is not allowed to assign or copy an instance of this class.
62cdf0e10cSrcweir 
63cdf0e10cSrcweir   @see OInterfaceContainerHelper
64cdf0e10cSrcweir  */
65*ebbaf3b8SDamjan Jovanovic class CPPUHELPER_DLLPUBLIC OInterfaceIteratorHelper
66cdf0e10cSrcweir {
67cdf0e10cSrcweir public:
68cdf0e10cSrcweir 	/**
69cdf0e10cSrcweir 	   Create an iterator over the elements of the container. The iterator
70cdf0e10cSrcweir 	   copies the elements of the conatainer. A change to the container
71cdf0e10cSrcweir        during the lifetime of an iterator is allowed and does not
72cdf0e10cSrcweir 	   affect the iterator-instance. The iterator and the container take cares
73cdf0e10cSrcweir        themself for concurrent access, no additional guarding is necessary.
74cdf0e10cSrcweir 
75cdf0e10cSrcweir 	   Remark: The copy is on demand. The iterator copy the elements only if the container
76cdf0e10cSrcweir 	   change the contents. It is not allowed to destroy the container as long
77cdf0e10cSrcweir        as an iterator exist.
78cdf0e10cSrcweir 
79cdf0e10cSrcweir 	   @param rCont	the container of the elements.
80cdf0e10cSrcweir 	 */
81cdf0e10cSrcweir 	OInterfaceIteratorHelper( OInterfaceContainerHelper & rCont ) SAL_THROW( () );
82cdf0e10cSrcweir 
83cdf0e10cSrcweir 	/**
84cdf0e10cSrcweir 	  Releases the connection to the container.
85cdf0e10cSrcweir 	 */
86cdf0e10cSrcweir 	~OInterfaceIteratorHelper() SAL_THROW( () );
87cdf0e10cSrcweir 
88cdf0e10cSrcweir 	/** Return sal_True, if there are more elements in the iterator. */
hasMoreElements() const89cdf0e10cSrcweir 	sal_Bool SAL_CALL hasMoreElements() const SAL_THROW( () )
90cdf0e10cSrcweir 		{ return nRemain != 0; }
91cdf0e10cSrcweir 	/** Return the next element of the iterator. Calling this method if
92cdf0e10cSrcweir 	    hasMoreElements() has returned sal_False, is an error. Cast the
93cdf0e10cSrcweir         returned pointer to the
94cdf0e10cSrcweir 	 */
95cdf0e10cSrcweir 	::com::sun::star::uno::XInterface *	SAL_CALL next() SAL_THROW( () );
96cdf0e10cSrcweir 
97cdf0e10cSrcweir 	/** Removes the current element (the last one returned by next())
98cdf0e10cSrcweir 	    from the underlying container. Calling this method before
99cdf0e10cSrcweir 		next() has been called or calling it twice with no next()
100cdf0e10cSrcweir 		inbetween is an error.
101cdf0e10cSrcweir 	*/
102cdf0e10cSrcweir 	void SAL_CALL remove() SAL_THROW( () );
103cdf0e10cSrcweir 
104cdf0e10cSrcweir private:
105cdf0e10cSrcweir 	OInterfaceContainerHelper &	rCont;
106cdf0e10cSrcweir 	sal_Bool					bIsList;
107cdf0e10cSrcweir 
108cdf0e10cSrcweir     detail::element_alias aData;
109cdf0e10cSrcweir 
110cdf0e10cSrcweir 	sal_Int32					nRemain;
111cdf0e10cSrcweir 
112cdf0e10cSrcweir 	OInterfaceIteratorHelper( const OInterfaceIteratorHelper & ) SAL_THROW( () );
113cdf0e10cSrcweir 	OInterfaceIteratorHelper &	operator = ( const OInterfaceIteratorHelper & ) SAL_THROW( () );
114cdf0e10cSrcweir };
115cdf0e10cSrcweir 
116cdf0e10cSrcweir //===================================================================
117cdf0e10cSrcweir /**
118cdf0e10cSrcweir   A container of interfaces. To access the elements use an iterator.
119cdf0e10cSrcweir   This implementation is thread save.
120cdf0e10cSrcweir 
121cdf0e10cSrcweir   @see OInterfaceIteratorHelper
122cdf0e10cSrcweir  */
123*ebbaf3b8SDamjan Jovanovic class CPPUHELPER_DLLPUBLIC OInterfaceContainerHelper
124cdf0e10cSrcweir {
125cdf0e10cSrcweir public:
126cdf0e10cSrcweir 	// these are here to force memory de/allocation to sal lib.
operator new(size_t nSize)127cdf0e10cSrcweir 	inline static void * SAL_CALL operator new( size_t nSize ) SAL_THROW( () )
128cdf0e10cSrcweir 		{ return ::rtl_allocateMemory( nSize ); }
operator delete(void * pMem)129cdf0e10cSrcweir 	inline static void SAL_CALL operator delete( void * pMem ) SAL_THROW( () )
130cdf0e10cSrcweir 		{ ::rtl_freeMemory( pMem ); }
operator new(size_t,void * pMem)131cdf0e10cSrcweir 	inline static void * SAL_CALL operator new( size_t, void * pMem ) SAL_THROW( () )
132cdf0e10cSrcweir 		{ return pMem; }
operator delete(void *,void *)133cdf0e10cSrcweir 	inline static void SAL_CALL operator delete( void *, void * ) SAL_THROW( () )
134cdf0e10cSrcweir 		{}
135cdf0e10cSrcweir 
136cdf0e10cSrcweir 	/**
137cdf0e10cSrcweir 	   Create an interface container.
138cdf0e10cSrcweir 
139cdf0e10cSrcweir 	   @param rMutex	the mutex to protect multi thread access.
140cdf0e10cSrcweir        The lifetime must be longer than the lifetime
141cdf0e10cSrcweir 	   of this object.
142cdf0e10cSrcweir 	 */
143cdf0e10cSrcweir 	OInterfaceContainerHelper( ::osl::Mutex & rMutex ) SAL_THROW( () );
144cdf0e10cSrcweir 	/**
145cdf0e10cSrcweir 	  Release all interfaces. All iterators must be destroyed before
146cdf0e10cSrcweir 	  the container is destructed.
147cdf0e10cSrcweir 	 */
148cdf0e10cSrcweir 	~OInterfaceContainerHelper() SAL_THROW( () );
149cdf0e10cSrcweir 	/**
150cdf0e10cSrcweir 	  Return the number of Elements in the container. Only useful if you have acquired
151cdf0e10cSrcweir 	  the mutex.
152cdf0e10cSrcweir 	 */
153cdf0e10cSrcweir 	sal_Int32 SAL_CALL getLength() const SAL_THROW( () );
154cdf0e10cSrcweir 
155cdf0e10cSrcweir 	/**
156cdf0e10cSrcweir 	  Return all interfaces added to this container.
157cdf0e10cSrcweir 	 **/
158cdf0e10cSrcweir 	::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > > SAL_CALL getElements() const SAL_THROW( () );
159cdf0e10cSrcweir 
160cdf0e10cSrcweir 	/** Inserts an element into the container.  The position is not specified, thus it is not
161cdf0e10cSrcweir         specified in which order events are fired.
162cdf0e10cSrcweir 
163cdf0e10cSrcweir         @attention
164cdf0e10cSrcweir         If you add the same interface more than once, then it will be added to the elements list
165cdf0e10cSrcweir         more than once and thus if you want to remove that interface from the list, you have to call
166cdf0e10cSrcweir         removeInterface() the same number of times.
167cdf0e10cSrcweir         In the latter case, you will also get events fired more than once (if the interface is a
168cdf0e10cSrcweir         listener interface).
169cdf0e10cSrcweir 
170cdf0e10cSrcweir         @param rxIFace
171cdf0e10cSrcweir                interface to be added; it is allowed to insert null or
172cdf0e10cSrcweir                the same interface more than once
173cdf0e10cSrcweir         @return
174cdf0e10cSrcweir                 the new count of elements in the container
175cdf0e10cSrcweir     */
176cdf0e10cSrcweir 	sal_Int32 SAL_CALL addInterface( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > & rxIFace ) SAL_THROW( () );
177cdf0e10cSrcweir 	/** Removes an element from the container.  It uses interface equality to remove the interface.
178cdf0e10cSrcweir 
179cdf0e10cSrcweir         @param rxIFace
180cdf0e10cSrcweir                interface to be removed
181cdf0e10cSrcweir         @return
182cdf0e10cSrcweir                 the new count of elements in the container
183cdf0e10cSrcweir     */
184cdf0e10cSrcweir 	sal_Int32 SAL_CALL removeInterface( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > & rxIFace ) SAL_THROW( () );
185cdf0e10cSrcweir 	/**
186cdf0e10cSrcweir 	  Call disposing on all object in the container that
187cdf0e10cSrcweir 	  support XEventListener. Than clear the container.
188cdf0e10cSrcweir 	 */
189cdf0e10cSrcweir 	void SAL_CALL disposeAndClear( const ::com::sun::star::lang::EventObject & rEvt ) SAL_THROW( () );
190cdf0e10cSrcweir 	/**
191cdf0e10cSrcweir 	  Clears the container without calling disposing().
192cdf0e10cSrcweir 	 */
193cdf0e10cSrcweir 	void SAL_CALL clear() SAL_THROW( () );
194cdf0e10cSrcweir 
195cdf0e10cSrcweir     /** Executes a functor for each contained listener of specified type, e.g.
196cdf0e10cSrcweir         <code>forEach<awt::XPaintListener>(...</code>.
197cdf0e10cSrcweir 
198cdf0e10cSrcweir         If a com::sun::star::lang::DisposedException occurs which relates to
199cdf0e10cSrcweir         the called listener, then that listener is removed from the container.
200cdf0e10cSrcweir 
201cdf0e10cSrcweir         @tpl ListenerT listener type
202cdf0e10cSrcweir         @tpl FuncT unary functor type, let your compiler deduce this for you
203cdf0e10cSrcweir         @param func unary functor object expecting an argument of type
204cdf0e10cSrcweir                     ::com::sun::star::uno::Reference<ListenerT>
205cdf0e10cSrcweir     */
206cdf0e10cSrcweir     template <typename ListenerT, typename FuncT>
207cdf0e10cSrcweir     inline void forEach( FuncT const& func );
208cdf0e10cSrcweir 
209cdf0e10cSrcweir     /** Calls a UNO listener method for each contained listener.
210cdf0e10cSrcweir 
211cdf0e10cSrcweir         The listener method must take a single argument of type EventT,
212cdf0e10cSrcweir         and return <code>void</code>.
213cdf0e10cSrcweir 
214cdf0e10cSrcweir         If a com::sun::star::lang::DisposedException occurs which relates to
215cdf0e10cSrcweir         the called listener, then that listener is removed from the container.
216cdf0e10cSrcweir 
217cdf0e10cSrcweir         @tpl ListenerT UNO event listener type, let your compiler deduce this for you
218cdf0e10cSrcweir         @tpl EventT event type, let your compiler deduce this for you
219cdf0e10cSrcweir         @param NotificationMethod
220cdf0e10cSrcweir             Pointer to a method of a ListenerT interface.
221cdf0e10cSrcweir         @param Event
222cdf0e10cSrcweir             Event to notify to all contained listeners
223cdf0e10cSrcweir 
224cdf0e10cSrcweir         @example
225cdf0e10cSrcweir <pre>
226cdf0e10cSrcweir     awt::PaintEvent aEvent( static_cast< ::cppu::OWeakObject* >( this ), ... );
227cdf0e10cSrcweir     listeners.notifyEach( &XPaintListener::windowPaint, aEvent );
228cdf0e10cSrcweir </pre>
229cdf0e10cSrcweir     */
230cdf0e10cSrcweir     template< typename ListenerT, typename EventT >
231cdf0e10cSrcweir     inline void notifyEach( void ( SAL_CALL ListenerT::*NotificationMethod )( const EventT& ), const EventT& Event );
232cdf0e10cSrcweir 
233cdf0e10cSrcweir private:
234cdf0e10cSrcweir friend class OInterfaceIteratorHelper;
235cdf0e10cSrcweir 	/**
236cdf0e10cSrcweir 	  bIsList == TRUE -> aData.pAsSequence of type Sequence< XInterfaceSequence >,
237cdf0e10cSrcweir 	  otherwise aData.pAsInterface == of type (XEventListener *)
238cdf0e10cSrcweir 	 */
239cdf0e10cSrcweir     detail::element_alias   aData;
240cdf0e10cSrcweir 	::osl::Mutex &			rMutex;
241cdf0e10cSrcweir 	/** TRUE -> used by an iterator. */
242cdf0e10cSrcweir 	sal_Bool				bInUse;
243cdf0e10cSrcweir 	/** TRUE -> aData.pAsSequence is of type Sequence< XInterfaceSequence >. */
244cdf0e10cSrcweir 	sal_Bool				bIsList;
245cdf0e10cSrcweir 
246cdf0e10cSrcweir 	OInterfaceContainerHelper( const OInterfaceContainerHelper & ) SAL_THROW( () );
247cdf0e10cSrcweir 	OInterfaceContainerHelper & operator = ( const OInterfaceContainerHelper & ) SAL_THROW( () );
248cdf0e10cSrcweir 
249cdf0e10cSrcweir 	/*
250cdf0e10cSrcweir 	  Dulicate content of the conaitner and release the old one without destroying.
251cdf0e10cSrcweir 	  The mutex must be locked and the memberbInUse must be true.
252cdf0e10cSrcweir 	 */
253cdf0e10cSrcweir 	void copyAndResetInUse() SAL_THROW( () );
254cdf0e10cSrcweir 
255cdf0e10cSrcweir private:
256cdf0e10cSrcweir     template< typename ListenerT, typename EventT >
257cdf0e10cSrcweir     class NotifySingleListener
258cdf0e10cSrcweir     {
259cdf0e10cSrcweir     private:
260cdf0e10cSrcweir         typedef void ( SAL_CALL ListenerT::*NotificationMethod )( const EventT& );
261cdf0e10cSrcweir         NotificationMethod  m_pMethod;
262cdf0e10cSrcweir         const EventT&       m_rEvent;
263cdf0e10cSrcweir     public:
NotifySingleListener(NotificationMethod method,const EventT & event)264cdf0e10cSrcweir         NotifySingleListener( NotificationMethod method, const EventT& event ) : m_pMethod( method ), m_rEvent( event ) { }
265cdf0e10cSrcweir 
operator ()(const::com::sun::star::uno::Reference<ListenerT> & listener) const266cdf0e10cSrcweir         void operator()( const ::com::sun::star::uno::Reference<ListenerT>& listener ) const
267cdf0e10cSrcweir         {
268cdf0e10cSrcweir             (listener.get()->*m_pMethod)( m_rEvent );
269cdf0e10cSrcweir         }
270cdf0e10cSrcweir     };
271cdf0e10cSrcweir };
272cdf0e10cSrcweir 
273cdf0e10cSrcweir template <typename ListenerT, typename FuncT>
forEach(FuncT const & func)274cdf0e10cSrcweir inline void OInterfaceContainerHelper::forEach( FuncT const& func )
275cdf0e10cSrcweir {
276cdf0e10cSrcweir     OInterfaceIteratorHelper iter( *this );
277cdf0e10cSrcweir     while (iter.hasMoreElements()) {
278cdf0e10cSrcweir         ::com::sun::star::uno::Reference<ListenerT> const xListener(
279cdf0e10cSrcweir             iter.next(), ::com::sun::star::uno::UNO_QUERY );
280cdf0e10cSrcweir         if (xListener.is()) {
281cdf0e10cSrcweir #if defined(EXCEPTIONS_OFF)
282cdf0e10cSrcweir             func( xListener );
283cdf0e10cSrcweir #else
284cdf0e10cSrcweir             try {
285cdf0e10cSrcweir                 func( xListener );
286cdf0e10cSrcweir             }
287cdf0e10cSrcweir             catch (::com::sun::star::lang::DisposedException const& exc) {
288cdf0e10cSrcweir                 if (exc.Context == xListener)
289cdf0e10cSrcweir                     iter.remove();
290cdf0e10cSrcweir             }
291cdf0e10cSrcweir #endif
292cdf0e10cSrcweir         }
293cdf0e10cSrcweir     }
294cdf0e10cSrcweir }
295cdf0e10cSrcweir 
296cdf0e10cSrcweir template< typename ListenerT, typename EventT >
notifyEach(void (SAL_CALL ListenerT::* NotificationMethod)(const EventT &),const EventT & Event)297cdf0e10cSrcweir inline void OInterfaceContainerHelper::notifyEach( void ( SAL_CALL ListenerT::*NotificationMethod )( const EventT& ), const EventT& Event )
298cdf0e10cSrcweir {
299cdf0e10cSrcweir     forEach< ListenerT, NotifySingleListener< ListenerT, EventT > >( NotifySingleListener< ListenerT, EventT >( NotificationMethod, Event ) );
300cdf0e10cSrcweir }
301cdf0e10cSrcweir 
302cdf0e10cSrcweir //===================================================================
303cdf0e10cSrcweir /**
304cdf0e10cSrcweir   A helper class to store interface references of different types.
305cdf0e10cSrcweir 
306cdf0e10cSrcweir   @see OInterfaceIteratorHelper
307cdf0e10cSrcweir   @see OInterfaceContainerHelper
308cdf0e10cSrcweir  */
309cdf0e10cSrcweir template< class key , class hashImpl , class equalImpl >
310cdf0e10cSrcweir class OMultiTypeInterfaceContainerHelperVar
311cdf0e10cSrcweir {
312cdf0e10cSrcweir public:
313cdf0e10cSrcweir 	// these are here to force memory de/allocation to sal lib.
operator new(size_t nSize)314cdf0e10cSrcweir 	inline static void * SAL_CALL operator new( size_t nSize ) SAL_THROW( () )
315cdf0e10cSrcweir 		{ return ::rtl_allocateMemory( nSize ); }
operator delete(void * pMem)316cdf0e10cSrcweir 	inline static void SAL_CALL operator delete( void * pMem ) SAL_THROW( () )
317cdf0e10cSrcweir 		{ ::rtl_freeMemory( pMem ); }
operator new(size_t,void * pMem)318cdf0e10cSrcweir 	inline static void * SAL_CALL operator new( size_t, void * pMem ) SAL_THROW( () )
319cdf0e10cSrcweir 		{ return pMem; }
operator delete(void *,void *)320cdf0e10cSrcweir 	inline static void SAL_CALL operator delete( void *, void * ) SAL_THROW( () )
321cdf0e10cSrcweir 		{}
322cdf0e10cSrcweir 
323cdf0e10cSrcweir 	/**
324cdf0e10cSrcweir 	  Create a container of interface containers.
325cdf0e10cSrcweir 
326cdf0e10cSrcweir 	  @param rMutex	the mutex to protect multi thread access.
327cdf0e10cSrcweir 	 					The lifetime must be longer than the lifetime
328cdf0e10cSrcweir 	 					of this object.
329cdf0e10cSrcweir 	 */
330cdf0e10cSrcweir 	inline OMultiTypeInterfaceContainerHelperVar( ::osl::Mutex & ) SAL_THROW( () );
331cdf0e10cSrcweir 	/**
332cdf0e10cSrcweir 	  Deletes all containers.
333cdf0e10cSrcweir 	 */
334cdf0e10cSrcweir 	inline ~OMultiTypeInterfaceContainerHelperVar() SAL_THROW( () );
335cdf0e10cSrcweir 
336cdf0e10cSrcweir 	/**
337cdf0e10cSrcweir 	  Return all id's under which at least one interface is added.
338cdf0e10cSrcweir 	 */
339cdf0e10cSrcweir 	inline ::com::sun::star::uno::Sequence< key > SAL_CALL getContainedTypes() const SAL_THROW( () );
340cdf0e10cSrcweir 
341cdf0e10cSrcweir 	/**
342cdf0e10cSrcweir 	  Return the container created under this key.
343cdf0e10cSrcweir       The InterfaceContainerHelper exists until the whole MultiTypeContainer is destroyed.
344cdf0e10cSrcweir 	  @return the container created under this key. If the container
345cdf0e10cSrcweir 	 			was not created, null was returned.
346cdf0e10cSrcweir 	 */
347cdf0e10cSrcweir 	inline OInterfaceContainerHelper * SAL_CALL getContainer( const key & ) const SAL_THROW( () );
348cdf0e10cSrcweir 
349cdf0e10cSrcweir 	/** Inserts an element into the container with the specified key.
350cdf0e10cSrcweir         The position is not specified, thus it is not specified in which order events are fired.
351cdf0e10cSrcweir 
352cdf0e10cSrcweir         @attention
353cdf0e10cSrcweir         If you add the same interface more than once, then it will be added to the elements list
354cdf0e10cSrcweir         more than once and thus if you want to remove that interface from the list, you have to call
355cdf0e10cSrcweir         removeInterface() the same number of times.
356cdf0e10cSrcweir         In the latter case, you will also get events fired more than once (if the interface is a
357cdf0e10cSrcweir         listener interface).
358cdf0e10cSrcweir 
359cdf0e10cSrcweir         @param rKey
360cdf0e10cSrcweir                the id of the container
361cdf0e10cSrcweir         @param r
362cdf0e10cSrcweir                interface to be added; it is allowed, to insert null or
363cdf0e10cSrcweir                the same interface more than once
364cdf0e10cSrcweir         @return
365cdf0e10cSrcweir                 the new count of elements in the container
366cdf0e10cSrcweir     */
367cdf0e10cSrcweir 	inline sal_Int32 SAL_CALL addInterface(
368cdf0e10cSrcweir 		const key & rKey,
369cdf0e10cSrcweir 		const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > & r )
370cdf0e10cSrcweir 		SAL_THROW( () );
371cdf0e10cSrcweir 
372cdf0e10cSrcweir 	/** Removes an element from the container with the specified key.
373cdf0e10cSrcweir         It uses interface equality to remove the interface.
374cdf0e10cSrcweir 
375cdf0e10cSrcweir         @param rKey
376cdf0e10cSrcweir                the id of the container
377cdf0e10cSrcweir         @param rxIFace
378cdf0e10cSrcweir                interface to be removed
379cdf0e10cSrcweir         @return
380cdf0e10cSrcweir                 the new count of elements in the container
381cdf0e10cSrcweir     */
382cdf0e10cSrcweir 	inline sal_Int32 SAL_CALL removeInterface(
383cdf0e10cSrcweir 		const key & rKey,
384cdf0e10cSrcweir 		const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > & rxIFace )
385cdf0e10cSrcweir 		SAL_THROW( () );
386cdf0e10cSrcweir 
387cdf0e10cSrcweir 	/**
388cdf0e10cSrcweir 	  Call disposing on all references in the container, that
389cdf0e10cSrcweir 	  support XEventListener. Then clears the container.
390cdf0e10cSrcweir       @param rEvt the event object which is passed during disposing() call
391cdf0e10cSrcweir 	 */
392cdf0e10cSrcweir 	inline void	SAL_CALL disposeAndClear( const ::com::sun::star::lang::EventObject & rEvt ) SAL_THROW( () );
393cdf0e10cSrcweir 	/**
394cdf0e10cSrcweir 	  Remove all elements of all containers. Does not delete the container.
395cdf0e10cSrcweir 	 */
396cdf0e10cSrcweir 	inline void SAL_CALL clear() SAL_THROW( () );
397cdf0e10cSrcweir 
398cdf0e10cSrcweir 	typedef key keyType;
399cdf0e10cSrcweir private:
400cdf0e10cSrcweir     typedef ::std::vector< std::pair < key , void* > > InterfaceMap;
401cdf0e10cSrcweir     InterfaceMap *m_pMap;
402cdf0e10cSrcweir 	::osl::Mutex &	rMutex;
403cdf0e10cSrcweir 
find(const key & rKey) const404cdf0e10cSrcweir     inline typename InterfaceMap::iterator find(const key &rKey) const
405cdf0e10cSrcweir     {
406cdf0e10cSrcweir         typename InterfaceMap::iterator iter = m_pMap->begin();
407cdf0e10cSrcweir         typename InterfaceMap::iterator end = m_pMap->end();
408cdf0e10cSrcweir 
409cdf0e10cSrcweir     	while( iter != end )
410cdf0e10cSrcweir         {
411cdf0e10cSrcweir             equalImpl equal;
412cdf0e10cSrcweir             if( equal( iter->first, rKey ) )
413cdf0e10cSrcweir                 break;
414cdf0e10cSrcweir             iter++;
415cdf0e10cSrcweir         }
416cdf0e10cSrcweir         return iter;
417cdf0e10cSrcweir     }
418cdf0e10cSrcweir 
419cdf0e10cSrcweir 	inline OMultiTypeInterfaceContainerHelperVar( const OMultiTypeInterfaceContainerHelperVar & ) SAL_THROW( () );
420cdf0e10cSrcweir 	inline OMultiTypeInterfaceContainerHelperVar & operator = ( const OMultiTypeInterfaceContainerHelperVar & ) SAL_THROW( () );
421cdf0e10cSrcweir };
422cdf0e10cSrcweir 
423cdf0e10cSrcweir 
424cdf0e10cSrcweir 
425cdf0e10cSrcweir 
426cdf0e10cSrcweir /**
427cdf0e10cSrcweir   This struct contains the standard variables of a broadcaster. Helper
428cdf0e10cSrcweir   classes only know a reference to this struct instead of references
429cdf0e10cSrcweir   to the four members. The access to the members must be guarded with
430cdf0e10cSrcweir   rMutex.
431cdf0e10cSrcweir 
432cdf0e10cSrcweir   The additional template parameter keyType has been added, because gcc
433cdf0e10cSrcweir   can't compile addListener( const container::keyType &key ).
434cdf0e10cSrcweir  */
435cdf0e10cSrcweir template < class container , class keyType >
436cdf0e10cSrcweir struct OBroadcastHelperVar
437cdf0e10cSrcweir {
438cdf0e10cSrcweir 	/** The shared mutex. */
439cdf0e10cSrcweir 	::osl::Mutex &						rMutex;
440cdf0e10cSrcweir 	/** ListenerContainer class is thread save. */
441cdf0e10cSrcweir 	container	aLC;
442cdf0e10cSrcweir 	/** Dispose call ready. */
443cdf0e10cSrcweir 	sal_Bool							bDisposed;
444cdf0e10cSrcweir 	/** In dispose call. */
445cdf0e10cSrcweir 	sal_Bool							bInDispose;
446cdf0e10cSrcweir 
447cdf0e10cSrcweir 	/**
448cdf0e10cSrcweir 	  Initialize the structur. bDispose and bInDispose are set to false.
449cdf0e10cSrcweir 	  @param rMutex the mutex reference.
450cdf0e10cSrcweir 	 */
451cdf0e10cSrcweir 	OBroadcastHelperVar( ::osl::Mutex & rMutex_ ) SAL_THROW( () )
452cdf0e10cSrcweir 		: rMutex( rMutex_ )
453cdf0e10cSrcweir 		, aLC( rMutex_ )
454cdf0e10cSrcweir 		, bDisposed( sal_False )
455cdf0e10cSrcweir 		, bInDispose( sal_False )
456cdf0e10cSrcweir 	{}
457cdf0e10cSrcweir 
458cdf0e10cSrcweir 	/**
459cdf0e10cSrcweir 	  adds a listener threadsafe.
460cdf0e10cSrcweir 	 **/
addListenercppu::OBroadcastHelperVar461cdf0e10cSrcweir 	inline void addListener(
462cdf0e10cSrcweir 		const keyType &key,
463cdf0e10cSrcweir 		const ::com::sun::star::uno::Reference < ::com::sun::star::uno::XInterface > &r )
464cdf0e10cSrcweir 		SAL_THROW( () )
465cdf0e10cSrcweir 	{
466cdf0e10cSrcweir 		::osl::MutexGuard guard( rMutex );
467cdf0e10cSrcweir 		OSL_ENSURE( !bInDispose, "do not add listeners in the dispose call" );
468cdf0e10cSrcweir 		OSL_ENSURE( !bDisposed, "object is disposed" );
469cdf0e10cSrcweir 		if( ! bInDispose && ! bDisposed  )
470cdf0e10cSrcweir 			aLC.addInterface( key , r );
471cdf0e10cSrcweir 	}
472cdf0e10cSrcweir 
473cdf0e10cSrcweir 	/**
474cdf0e10cSrcweir 	  removes a listener threadsafe
475cdf0e10cSrcweir 	 **/
removeListenercppu::OBroadcastHelperVar476cdf0e10cSrcweir 	inline void removeListener(
477cdf0e10cSrcweir 		const keyType &key,
478cdf0e10cSrcweir 		const ::com::sun::star::uno::Reference < ::com::sun::star::uno::XInterface > & r )
479cdf0e10cSrcweir 		SAL_THROW( () )
480cdf0e10cSrcweir 	{
481cdf0e10cSrcweir 		::osl::MutexGuard guard( rMutex );
482cdf0e10cSrcweir 		OSL_ENSURE( !bDisposed, "object is disposed" );
483cdf0e10cSrcweir 		if( ! bInDispose && ! bDisposed  )
484cdf0e10cSrcweir 			aLC.removeInterface( key , r );
485cdf0e10cSrcweir 	}
486cdf0e10cSrcweir 
487cdf0e10cSrcweir 	/**
488cdf0e10cSrcweir 	  Return the container created under this key.
489cdf0e10cSrcweir 	  @return the container created under this key. If the container
490cdf0e10cSrcweir 	 		   was not created, null was returned. This can be used to optimize
491cdf0e10cSrcweir 	          performance ( construction of an event object can be avoided ).
492cdf0e10cSrcweir 	 ***/
getContainercppu::OBroadcastHelperVar493cdf0e10cSrcweir 	inline OInterfaceContainerHelper * SAL_CALL getContainer( const keyType &key ) const SAL_THROW( () )
494cdf0e10cSrcweir 		{ return aLC.getContainer( key ); }
495cdf0e10cSrcweir };
496cdf0e10cSrcweir 
497cdf0e10cSrcweir /*------------------------------------------
498cdf0e10cSrcweir *
499cdf0e10cSrcweir * In general, the above templates are used with a Type as key.
500cdf0e10cSrcweir * Therefore a default declaration is given ( OMultiTypeInterfaceContainerHelper and OBroadcastHelper )
501cdf0e10cSrcweir *
502cdf0e10cSrcweir *------------------------------------------*/
503cdf0e10cSrcweir 
504cdf0e10cSrcweir // helper function call class
505cdf0e10cSrcweir struct hashType_Impl
506cdf0e10cSrcweir {
operator ()cppu::hashType_Impl507cdf0e10cSrcweir 	size_t operator()(const ::com::sun::star::uno::Type & s) const SAL_THROW( () )
508cdf0e10cSrcweir 		{ return s.getTypeName().hashCode(); }
509cdf0e10cSrcweir };
510cdf0e10cSrcweir 
511cdf0e10cSrcweir 
512cdf0e10cSrcweir /** Specialized class for key type com::sun::star::uno::Type,
513cdf0e10cSrcweir     without explicit usage of STL symbols.
514cdf0e10cSrcweir */
515*ebbaf3b8SDamjan Jovanovic class CPPUHELPER_DLLPUBLIC OMultiTypeInterfaceContainerHelper
516cdf0e10cSrcweir {
517cdf0e10cSrcweir public:
518cdf0e10cSrcweir 	// these are here to force memory de/allocation to sal lib.
operator new(size_t nSize)519cdf0e10cSrcweir 	inline static void * SAL_CALL operator new( size_t nSize ) SAL_THROW( () )
520cdf0e10cSrcweir 		{ return ::rtl_allocateMemory( nSize ); }
operator delete(void * pMem)521cdf0e10cSrcweir 	inline static void SAL_CALL operator delete( void * pMem ) SAL_THROW( () )
522cdf0e10cSrcweir 		{ ::rtl_freeMemory( pMem ); }
operator new(size_t,void * pMem)523cdf0e10cSrcweir 	inline static void * SAL_CALL operator new( size_t, void * pMem ) SAL_THROW( () )
524cdf0e10cSrcweir 		{ return pMem; }
operator delete(void *,void *)525cdf0e10cSrcweir 	inline static void SAL_CALL operator delete( void *, void * ) SAL_THROW( () )
526cdf0e10cSrcweir 		{}
527cdf0e10cSrcweir 
528cdf0e10cSrcweir 	/**
529cdf0e10cSrcweir 	  Create a container of interface containers.
530cdf0e10cSrcweir 
531cdf0e10cSrcweir 	  @param rMutex	the mutex to protect multi thread access.
532cdf0e10cSrcweir 	 					The lifetime must be longer than the lifetime
533cdf0e10cSrcweir 	 					of this object.
534cdf0e10cSrcweir 	 */
535cdf0e10cSrcweir 	OMultiTypeInterfaceContainerHelper( ::osl::Mutex & ) SAL_THROW( () );
536cdf0e10cSrcweir 	/**
537cdf0e10cSrcweir 	  Delete all containers.
538cdf0e10cSrcweir 	 */
539cdf0e10cSrcweir 	~OMultiTypeInterfaceContainerHelper() SAL_THROW( () );
540cdf0e10cSrcweir 
541cdf0e10cSrcweir 	/**
542cdf0e10cSrcweir 	  Return all id's under which at least one interface is added.
543cdf0e10cSrcweir 	 */
544cdf0e10cSrcweir 	::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getContainedTypes() const SAL_THROW( () );
545cdf0e10cSrcweir 
546cdf0e10cSrcweir 	/**
547cdf0e10cSrcweir 	  Return the container created under this key.
548cdf0e10cSrcweir 	  @return the container created under this key. If the container
549cdf0e10cSrcweir 	 			was not created, null was returned.
550cdf0e10cSrcweir 	 */
551cdf0e10cSrcweir 	OInterfaceContainerHelper * SAL_CALL getContainer( const ::com::sun::star::uno::Type & rKey ) const SAL_THROW( () );
552cdf0e10cSrcweir 
553cdf0e10cSrcweir 	/** Inserts an element into the container with the specified key.
554cdf0e10cSrcweir         The position is not specified, thus it is not specified in which order events are fired.
555cdf0e10cSrcweir 
556cdf0e10cSrcweir         @attention
557cdf0e10cSrcweir         If you add the same interface more than once, then it will be added to the elements list
558cdf0e10cSrcweir         more than once and thus if you want to remove that interface from the list, you have to call
559cdf0e10cSrcweir         removeInterface() the same number of times.
560cdf0e10cSrcweir         In the latter case, you will also get events fired more than once (if the interface is a
561cdf0e10cSrcweir         listener interface).
562cdf0e10cSrcweir 
563cdf0e10cSrcweir         @param rKey
564cdf0e10cSrcweir                the id of the container
565cdf0e10cSrcweir         @param r
566cdf0e10cSrcweir                interface to be added; it is allowed, to insert null or
567cdf0e10cSrcweir                the same interface more than once
568cdf0e10cSrcweir         @return
569cdf0e10cSrcweir                 the new count of elements in the container
570cdf0e10cSrcweir     */
571cdf0e10cSrcweir 	sal_Int32 SAL_CALL addInterface(
572cdf0e10cSrcweir 		const ::com::sun::star::uno::Type & rKey,
573cdf0e10cSrcweir 		const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > & r )
574cdf0e10cSrcweir 		SAL_THROW( () );
575cdf0e10cSrcweir 
576cdf0e10cSrcweir 	/** Removes an element from the container with the specified key.
577cdf0e10cSrcweir         It uses interface equality to remove the interface.
578cdf0e10cSrcweir 
579cdf0e10cSrcweir         @param rKey
580cdf0e10cSrcweir                the id of the container
581cdf0e10cSrcweir         @param rxIFace
582cdf0e10cSrcweir                interface to be removed
583cdf0e10cSrcweir         @return
584cdf0e10cSrcweir                 the new count of elements in the container
585cdf0e10cSrcweir     */
586cdf0e10cSrcweir 	sal_Int32 SAL_CALL removeInterface(
587cdf0e10cSrcweir 		const ::com::sun::star::uno::Type & rKey,
588cdf0e10cSrcweir 		const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > & rxIFace )
589cdf0e10cSrcweir 		SAL_THROW( () );
590cdf0e10cSrcweir 
591cdf0e10cSrcweir 	/**
592cdf0e10cSrcweir 	  Call disposing on all object in the container that
593cdf0e10cSrcweir 	  support XEventListener. Than clear the container.
594cdf0e10cSrcweir 	 */
595cdf0e10cSrcweir 	void	SAL_CALL disposeAndClear( const ::com::sun::star::lang::EventObject & rEvt ) SAL_THROW( () );
596cdf0e10cSrcweir 	/**
597cdf0e10cSrcweir 	  Remove all elements of all containers. Does not delete the container.
598cdf0e10cSrcweir 	 */
599cdf0e10cSrcweir 	void SAL_CALL clear() SAL_THROW( () );
600cdf0e10cSrcweir 
601cdf0e10cSrcweir 	typedef ::com::sun::star::uno::Type keyType;
602cdf0e10cSrcweir private:
603cdf0e10cSrcweir 	void *m_pMap;
604cdf0e10cSrcweir 	::osl::Mutex &	rMutex;
605cdf0e10cSrcweir 
606cdf0e10cSrcweir 	inline OMultiTypeInterfaceContainerHelper( const OMultiTypeInterfaceContainerHelper & ) SAL_THROW( () );
607cdf0e10cSrcweir 	inline OMultiTypeInterfaceContainerHelper & operator = ( const OMultiTypeInterfaceContainerHelper & ) SAL_THROW( () );
608cdf0e10cSrcweir };
609cdf0e10cSrcweir 
610cdf0e10cSrcweir typedef OBroadcastHelperVar< OMultiTypeInterfaceContainerHelper , OMultiTypeInterfaceContainerHelper::keyType > OBroadcastHelper;
611cdf0e10cSrcweir 
612cdf0e10cSrcweir }
613cdf0e10cSrcweir 
614cdf0e10cSrcweir #endif
615cdf0e10cSrcweir 
616