00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef _CPPUHELPER_INTERFACECONTAINER_H_
00020 #define _CPPUHELPER_INTERFACECONTAINER_H_
00021
00022 #include <vector>
00023 #include <osl/mutex.hxx>
00024 #include <rtl/alloc.h>
00025 #include <com/sun/star/uno/Sequence.hxx>
00026 #include <com/sun/star/uno/XInterface.hpp>
00027 #ifndef _COM_SUN_STAR_LANG_EVENTOBJECT_HXX_
00028 #include <com/sun/star/lang/EventObject.hpp>
00029 #endif
00030
00031 #ifndef _COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HXX_
00032 #include "com/sun/star/lang/DisposedException.hpp"
00033 #endif
00034 #include "cppuhelperdllapi.h"
00035
00037 namespace cppu
00038 {
00039
00040 namespace detail {
00041
00042 union element_alias
00043 {
00044 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > > *pAsSequence;
00045 ::com::sun::star::uno::XInterface * pAsInterface;
00046 element_alias() : pAsInterface(0) {}
00047 };
00048
00049 }
00050
00051
00052 class OInterfaceContainerHelper;
00060 class CPPUHELPER_DLLPUBLIC OInterfaceIteratorHelper
00061 {
00062 public:
00076 OInterfaceIteratorHelper( OInterfaceContainerHelper & rCont ) SAL_THROW(());
00077
00081 ~OInterfaceIteratorHelper() SAL_THROW(());
00082
00084 sal_Bool SAL_CALL hasMoreElements() const SAL_THROW(())
00085 { return nRemain != 0; }
00090 ::com::sun::star::uno::XInterface * SAL_CALL next() SAL_THROW(());
00091
00097 void SAL_CALL remove() SAL_THROW(());
00098
00099 private:
00100 OInterfaceContainerHelper & rCont;
00101 sal_Bool bIsList;
00102
00103 detail::element_alias aData;
00104
00105 sal_Int32 nRemain;
00106
00107 OInterfaceIteratorHelper( const OInterfaceIteratorHelper & ) SAL_THROW(());
00108 OInterfaceIteratorHelper & operator = ( const OInterfaceIteratorHelper & ) SAL_THROW(());
00109 };
00110
00111
00118 class CPPUHELPER_DLLPUBLIC OInterfaceContainerHelper
00119 {
00120 public:
00121
00122 inline static void * SAL_CALL operator new( size_t nSize ) SAL_THROW(())
00123 { return ::rtl_allocateMemory( nSize ); }
00124 inline static void SAL_CALL operator delete( void * pMem ) SAL_THROW(())
00125 { ::rtl_freeMemory( pMem ); }
00126 inline static void * SAL_CALL operator new( size_t, void * pMem ) SAL_THROW(())
00127 { return pMem; }
00128 inline static void SAL_CALL operator delete( void *, void * ) SAL_THROW(())
00129 {}
00130
00138 OInterfaceContainerHelper( ::osl::Mutex & rMutex ) SAL_THROW(());
00143 ~OInterfaceContainerHelper() SAL_THROW(());
00148 sal_Int32 SAL_CALL getLength() const SAL_THROW(());
00149
00153 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > > SAL_CALL getElements() const SAL_THROW(());
00154
00171 sal_Int32 SAL_CALL addInterface( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > & rxIFace ) SAL_THROW(());
00179 sal_Int32 SAL_CALL removeInterface( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > & rxIFace ) SAL_THROW(());
00184 void SAL_CALL disposeAndClear( const ::com::sun::star::lang::EventObject & rEvt ) SAL_THROW(());
00188 void SAL_CALL clear() SAL_THROW(());
00189
00201 template <typename ListenerT, typename FuncT>
00202 inline void forEach( FuncT const& func );
00203
00225 template< typename ListenerT, typename EventT >
00226 inline void notifyEach( void ( SAL_CALL ListenerT::*NotificationMethod )( const EventT& ), const EventT& Event );
00227
00228 private:
00229 friend class OInterfaceIteratorHelper;
00234 detail::element_alias aData;
00235 ::osl::Mutex & rMutex;
00237 sal_Bool bInUse;
00239 sal_Bool bIsList;
00240
00241 OInterfaceContainerHelper( const OInterfaceContainerHelper & ) SAL_THROW(());
00242 OInterfaceContainerHelper & operator = ( const OInterfaceContainerHelper & ) SAL_THROW(());
00243
00244
00245
00246
00247
00248 void copyAndResetInUse() SAL_THROW(());
00249
00250 private:
00251 template< typename ListenerT, typename EventT >
00252 class NotifySingleListener
00253 {
00254 private:
00255 typedef void ( SAL_CALL ListenerT::*NotificationMethod )( const EventT& );
00256 NotificationMethod m_pMethod;
00257 const EventT& m_rEvent;
00258 public:
00259 NotifySingleListener( NotificationMethod method, const EventT& event ) : m_pMethod( method ), m_rEvent( event ) { }
00260
00261 void operator()( const ::com::sun::star::uno::Reference<ListenerT>& listener ) const
00262 {
00263 (listener.get()->*m_pMethod)( m_rEvent );
00264 }
00265 };
00266 };
00267
00268 template <typename ListenerT, typename FuncT>
00269 inline void OInterfaceContainerHelper::forEach( FuncT const& func )
00270 {
00271 OInterfaceIteratorHelper iter( *this );
00272 while (iter.hasMoreElements()) {
00273 ::com::sun::star::uno::Reference<ListenerT> const xListener(
00274 iter.next(), ::com::sun::star::uno::UNO_QUERY );
00275 if (xListener.is()) {
00276 #if defined(EXCEPTIONS_OFF)
00277 func( xListener );
00278 #else
00279 try {
00280 func( xListener );
00281 }
00282 catch (::com::sun::star::lang::DisposedException const& exc) {
00283 if (exc.Context == xListener)
00284 iter.remove();
00285 }
00286 #endif
00287 }
00288 }
00289 }
00290
00291 template< typename ListenerT, typename EventT >
00292 inline void OInterfaceContainerHelper::notifyEach( void ( SAL_CALL ListenerT::*NotificationMethod )( const EventT& ), const EventT& Event )
00293 {
00294 forEach< ListenerT, NotifySingleListener< ListenerT, EventT > >( NotifySingleListener< ListenerT, EventT >( NotificationMethod, Event ) );
00295 }
00296
00297
00304 template< class key , class hashImpl , class equalImpl >
00305 class OMultiTypeInterfaceContainerHelperVar
00306 {
00307 public:
00308
00309 inline static void * SAL_CALL operator new( size_t nSize ) SAL_THROW(())
00310 { return ::rtl_allocateMemory( nSize ); }
00311 inline static void SAL_CALL operator delete( void * pMem ) SAL_THROW(())
00312 { ::rtl_freeMemory( pMem ); }
00313 inline static void * SAL_CALL operator new( size_t, void * pMem ) SAL_THROW(())
00314 { return pMem; }
00315 inline static void SAL_CALL operator delete( void *, void * ) SAL_THROW(())
00316 {}
00317
00325 inline OMultiTypeInterfaceContainerHelperVar( ::osl::Mutex & rMutex ) SAL_THROW(());
00329 inline ~OMultiTypeInterfaceContainerHelperVar() SAL_THROW(());
00330
00334 inline ::com::sun::star::uno::Sequence< key > SAL_CALL getContainedTypes() const SAL_THROW(());
00335
00342 inline OInterfaceContainerHelper * SAL_CALL getContainer( const key & ) const SAL_THROW(());
00343
00362 inline sal_Int32 SAL_CALL addInterface(
00363 const key & rKey,
00364 const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > & r )
00365 SAL_THROW(());
00366
00377 inline sal_Int32 SAL_CALL removeInterface(
00378 const key & rKey,
00379 const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > & rxIFace )
00380 SAL_THROW(());
00381
00387 inline void SAL_CALL disposeAndClear( const ::com::sun::star::lang::EventObject & rEvt ) SAL_THROW(());
00391 inline void SAL_CALL clear() SAL_THROW(());
00392
00393 typedef key keyType;
00394 private:
00395 typedef ::std::vector< std::pair < key , void* > > InterfaceMap;
00396 InterfaceMap *m_pMap;
00397 ::osl::Mutex & rMutex;
00398
00399 inline typename InterfaceMap::iterator find(const key &rKey) const
00400 {
00401 typename InterfaceMap::iterator iter = m_pMap->begin();
00402 typename InterfaceMap::iterator end = m_pMap->end();
00403
00404 while( iter != end )
00405 {
00406 equalImpl equal;
00407 if( equal( iter->first, rKey ) )
00408 break;
00409 iter++;
00410 }
00411 return iter;
00412 }
00413
00414 inline OMultiTypeInterfaceContainerHelperVar( const OMultiTypeInterfaceContainerHelperVar & ) SAL_THROW(());
00415 inline OMultiTypeInterfaceContainerHelperVar & operator = ( const OMultiTypeInterfaceContainerHelperVar & ) SAL_THROW(());
00416 };
00417
00418
00419
00420
00430 template < class container , class keyType >
00431 struct OBroadcastHelperVar
00432 {
00434 ::osl::Mutex & rMutex;
00436 container aLC;
00438 sal_Bool bDisposed;
00440 sal_Bool bInDispose;
00441
00446 OBroadcastHelperVar( ::osl::Mutex & rMutex_ ) SAL_THROW(())
00447 : rMutex( rMutex_ )
00448 , aLC( rMutex_ )
00449 , bDisposed( sal_False )
00450 , bInDispose( sal_False )
00451 {}
00452
00456 inline void addListener(
00457 const keyType &key,
00458 const ::com::sun::star::uno::Reference < ::com::sun::star::uno::XInterface > &r )
00459 SAL_THROW(())
00460 {
00461 ::osl::MutexGuard guard( rMutex );
00462 OSL_ENSURE( !bInDispose, "do not add listeners in the dispose call" );
00463 OSL_ENSURE( !bDisposed, "object is disposed" );
00464 if( ! bInDispose && ! bDisposed )
00465 aLC.addInterface( key , r );
00466 }
00467
00471 inline void removeListener(
00472 const keyType &key,
00473 const ::com::sun::star::uno::Reference < ::com::sun::star::uno::XInterface > & r )
00474 SAL_THROW(())
00475 {
00476 ::osl::MutexGuard guard( rMutex );
00477 OSL_ENSURE( !bDisposed, "object is disposed" );
00478 if( ! bInDispose && ! bDisposed )
00479 aLC.removeInterface( key , r );
00480 }
00481
00488 inline OInterfaceContainerHelper * SAL_CALL getContainer( const keyType &key ) const SAL_THROW(())
00489 { return aLC.getContainer( key ); }
00490 };
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500 struct hashType_Impl
00501 {
00502 size_t operator()(const ::com::sun::star::uno::Type & s) const SAL_THROW(())
00503 { return (size_t) s.getTypeName().hashCode(); }
00504 };
00505
00506
00510 class CPPUHELPER_DLLPUBLIC OMultiTypeInterfaceContainerHelper
00511 {
00512 public:
00513
00514 inline static void * SAL_CALL operator new( size_t nSize ) SAL_THROW(())
00515 { return ::rtl_allocateMemory( nSize ); }
00516 inline static void SAL_CALL operator delete( void * pMem ) SAL_THROW(())
00517 { ::rtl_freeMemory( pMem ); }
00518 inline static void * SAL_CALL operator new( size_t, void * pMem ) SAL_THROW(())
00519 { return pMem; }
00520 inline static void SAL_CALL operator delete( void *, void * ) SAL_THROW(())
00521 {}
00522
00530 OMultiTypeInterfaceContainerHelper( ::osl::Mutex & rMutex ) SAL_THROW(());
00534 ~OMultiTypeInterfaceContainerHelper() SAL_THROW(());
00535
00539 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getContainedTypes() const SAL_THROW(());
00540
00546 OInterfaceContainerHelper * SAL_CALL getContainer( const ::com::sun::star::uno::Type & rKey ) const SAL_THROW(());
00547
00566 sal_Int32 SAL_CALL addInterface(
00567 const ::com::sun::star::uno::Type & rKey,
00568 const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > & r )
00569 SAL_THROW(());
00570
00581 sal_Int32 SAL_CALL removeInterface(
00582 const ::com::sun::star::uno::Type & rKey,
00583 const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > & rxIFace )
00584 SAL_THROW(());
00585
00590 void SAL_CALL disposeAndClear( const ::com::sun::star::lang::EventObject & rEvt ) SAL_THROW(());
00594 void SAL_CALL clear() SAL_THROW(());
00595
00596 typedef ::com::sun::star::uno::Type keyType;
00597 private:
00598 void *m_pMap;
00599 ::osl::Mutex & rMutex;
00600
00601 inline OMultiTypeInterfaceContainerHelper( const OMultiTypeInterfaceContainerHelper & ) SAL_THROW(());
00602 inline OMultiTypeInterfaceContainerHelper & operator = ( const OMultiTypeInterfaceContainerHelper & ) SAL_THROW(());
00603 };
00604
00605 typedef OBroadcastHelperVar< OMultiTypeInterfaceContainerHelper , OMultiTypeInterfaceContainerHelper::keyType > OBroadcastHelper;
00606
00607 }
00608
00609 #endif
00610
00611