UDK 3.2.7 C/C++ API Reference
cppuhelper/interfacecontainer.h
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
00002 /*************************************************************************
00003  *
00004  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
00005  *
00006  * Copyright 2000, 2010 Oracle and/or its affiliates.
00007  *
00008  * OpenOffice.org - a multi-platform office productivity suite
00009  *
00010  * This file is part of OpenOffice.org.
00011  *
00012  * OpenOffice.org is free software: you can redistribute it and/or modify
00013  * it under the terms of the GNU Lesser General Public License version 3
00014  * only, as published by the Free Software Foundation.
00015  *
00016  * OpenOffice.org is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU Lesser General Public License version 3 for more details
00020  * (a copy is included in the LICENSE file that accompanied this code).
00021  *
00022  * You should have received a copy of the GNU Lesser General Public License
00023  * version 3 along with OpenOffice.org.  If not, see
00024  * <http://www.openoffice.org/license.html>
00025  * for a copy of the LGPLv3 License.
00026  *
00027  ************************************************************************/
00028 #ifndef _CPPUHELPER_INTERFACECONTAINER_H_
00029 #define _CPPUHELPER_INTERFACECONTAINER_H_
00030 
00031 #include <vector>
00032 #include <osl/mutex.hxx>
00033 #include <rtl/alloc.h>
00034 #include <com/sun/star/uno/Sequence.hxx>
00035 #include <com/sun/star/uno/XInterface.hpp>
00036 #ifndef _COM_SUN_STAR_LANG_EVENTOBJECT_HXX_
00037 #include <com/sun/star/lang/EventObject.hpp>
00038 #endif
00039 
00040 #ifndef _COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HXX_
00041 #include "com/sun/star/lang/DisposedException.hpp"
00042 #endif
00043 #include "cppuhelperdllapi.h"
00044  //for docpp
00046 namespace cppu
00047 {
00048 
00049 namespace detail {
00050 
00051     union element_alias
00052     {
00053         ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > > *pAsSequence;
00054         ::com::sun::star::uno::XInterface * pAsInterface;
00055         element_alias() : pAsInterface(0) {}
00056     };
00057 
00058 }
00059 
00060 //===================================================================
00061 class OInterfaceContainerHelper;
00069 class CPPUHELPER_DLLPUBLIC OInterfaceIteratorHelper
00070 {
00071 public:
00085     OInterfaceIteratorHelper( OInterfaceContainerHelper & rCont ) SAL_THROW(());
00086 
00090     ~OInterfaceIteratorHelper() SAL_THROW(());
00091 
00093     sal_Bool SAL_CALL hasMoreElements() const SAL_THROW(())
00094         { return nRemain != 0; }
00099     ::com::sun::star::uno::XInterface * SAL_CALL next() SAL_THROW(());
00100 
00106     void SAL_CALL remove() SAL_THROW(());
00107 
00108 private:
00109     OInterfaceContainerHelper & rCont;
00110     sal_Bool                    bIsList;
00111 
00112     detail::element_alias aData;
00113 
00114     sal_Int32                   nRemain;
00115 
00116     OInterfaceIteratorHelper( const OInterfaceIteratorHelper & ) SAL_THROW(());
00117     OInterfaceIteratorHelper &  operator = ( const OInterfaceIteratorHelper & ) SAL_THROW(());
00118 };
00119 
00120 //===================================================================
00127 class CPPUHELPER_DLLPUBLIC OInterfaceContainerHelper
00128 {
00129 public:
00130     // these are here to force memory de/allocation to sal lib.
00131     inline static void * SAL_CALL operator new( size_t nSize ) SAL_THROW(())
00132         { return ::rtl_allocateMemory( nSize ); }
00133     inline static void SAL_CALL operator delete( void * pMem ) SAL_THROW(())
00134         { ::rtl_freeMemory( pMem ); }
00135     inline static void * SAL_CALL operator new( size_t, void * pMem ) SAL_THROW(())
00136         { return pMem; }
00137     inline static void SAL_CALL operator delete( void *, void * ) SAL_THROW(())
00138         {}
00139 
00147     OInterfaceContainerHelper( ::osl::Mutex & rMutex ) SAL_THROW(());
00152     ~OInterfaceContainerHelper() SAL_THROW(());
00157     sal_Int32 SAL_CALL getLength() const SAL_THROW(());
00158 
00162     ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > > SAL_CALL getElements() const SAL_THROW(());
00163 
00180     sal_Int32 SAL_CALL addInterface( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > & rxIFace ) SAL_THROW(());
00188     sal_Int32 SAL_CALL removeInterface( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > & rxIFace ) SAL_THROW(());
00193     void SAL_CALL disposeAndClear( const ::com::sun::star::lang::EventObject & rEvt ) SAL_THROW(());
00197     void SAL_CALL clear() SAL_THROW(());
00198 
00210     template <typename ListenerT, typename FuncT>
00211     inline void forEach( FuncT const& func );
00212 
00234     template< typename ListenerT, typename EventT >
00235     inline void notifyEach( void ( SAL_CALL ListenerT::*NotificationMethod )( const EventT& ), const EventT& Event );
00236 
00237 private:
00238 friend class OInterfaceIteratorHelper;
00243     detail::element_alias   aData;
00244     ::osl::Mutex &          rMutex;
00246     sal_Bool                bInUse;
00248     sal_Bool                bIsList;
00249 
00250     OInterfaceContainerHelper( const OInterfaceContainerHelper & ) SAL_THROW(());
00251     OInterfaceContainerHelper & operator = ( const OInterfaceContainerHelper & ) SAL_THROW(());
00252 
00253     /*
00254       Dulicate content of the conaitner and release the old one without destroying.
00255       The mutex must be locked and the memberbInUse must be true.
00256      */
00257     void copyAndResetInUse() SAL_THROW(());
00258 
00259 private:
00260     template< typename ListenerT, typename EventT >
00261     class NotifySingleListener
00262     {
00263     private:
00264         typedef void ( SAL_CALL ListenerT::*NotificationMethod )( const EventT& );
00265         NotificationMethod  m_pMethod;
00266         const EventT&       m_rEvent;
00267     public:
00268         NotifySingleListener( NotificationMethod method, const EventT& event ) : m_pMethod( method ), m_rEvent( event ) { }
00269 
00270         void operator()( const ::com::sun::star::uno::Reference<ListenerT>& listener ) const
00271         {
00272             (listener.get()->*m_pMethod)( m_rEvent );
00273         }
00274     };
00275 };
00276 
00277 template <typename ListenerT, typename FuncT>
00278 inline void OInterfaceContainerHelper::forEach( FuncT const& func )
00279 {
00280     OInterfaceIteratorHelper iter( *this );
00281     while (iter.hasMoreElements()) {
00282         ::com::sun::star::uno::Reference<ListenerT> const xListener(
00283             iter.next(), ::com::sun::star::uno::UNO_QUERY );
00284         if (xListener.is()) {
00285 #if defined(EXCEPTIONS_OFF)
00286             func( xListener );
00287 #else
00288             try {
00289                 func( xListener );
00290             }
00291             catch (::com::sun::star::lang::DisposedException const& exc) {
00292                 if (exc.Context == xListener)
00293                     iter.remove();
00294             }
00295 #endif
00296         }
00297     }
00298 }
00299 
00300 template< typename ListenerT, typename EventT >
00301 inline void OInterfaceContainerHelper::notifyEach( void ( SAL_CALL ListenerT::*NotificationMethod )( const EventT& ), const EventT& Event )
00302 {
00303     forEach< ListenerT, NotifySingleListener< ListenerT, EventT > >( NotifySingleListener< ListenerT, EventT >( NotificationMethod, Event ) );
00304 }
00305 
00306 //===================================================================
00313 template< class key , class hashImpl , class equalImpl >
00314 class OMultiTypeInterfaceContainerHelperVar
00315 {
00316 public:
00317     // these are here to force memory de/allocation to sal lib.
00318     inline static void * SAL_CALL operator new( size_t nSize ) SAL_THROW(())
00319         { return ::rtl_allocateMemory( nSize ); }
00320     inline static void SAL_CALL operator delete( void * pMem ) SAL_THROW(())
00321         { ::rtl_freeMemory( pMem ); }
00322     inline static void * SAL_CALL operator new( size_t, void * pMem ) SAL_THROW(())
00323         { return pMem; }
00324     inline static void SAL_CALL operator delete( void *, void * ) SAL_THROW(())
00325         {}
00326 
00334     inline OMultiTypeInterfaceContainerHelperVar( ::osl::Mutex & rMutex ) SAL_THROW(());
00338     inline ~OMultiTypeInterfaceContainerHelperVar() SAL_THROW(());
00339 
00343     inline ::com::sun::star::uno::Sequence< key > SAL_CALL getContainedTypes() const SAL_THROW(());
00344 
00351     inline OInterfaceContainerHelper * SAL_CALL getContainer( const key & ) const SAL_THROW(());
00352 
00371     inline sal_Int32 SAL_CALL addInterface(
00372         const key & rKey,
00373         const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > & r )
00374         SAL_THROW(());
00375 
00386     inline sal_Int32 SAL_CALL removeInterface(
00387         const key & rKey,
00388         const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > & rxIFace )
00389         SAL_THROW(());
00390 
00396     inline void SAL_CALL disposeAndClear( const ::com::sun::star::lang::EventObject & rEvt ) SAL_THROW(());
00400     inline void SAL_CALL clear() SAL_THROW(());
00401 
00402     typedef key keyType;
00403 private:
00404     typedef ::std::vector< std::pair < key , void* > > InterfaceMap;
00405     InterfaceMap *m_pMap;
00406     ::osl::Mutex &  rMutex;
00407 
00408     inline typename InterfaceMap::iterator find(const key &rKey) const
00409     {
00410         typename InterfaceMap::iterator iter = m_pMap->begin();
00411         typename InterfaceMap::iterator end = m_pMap->end();
00412 
00413         while( iter != end )
00414         {
00415             equalImpl equal;
00416             if( equal( iter->first, rKey ) )
00417                 break;
00418             iter++;
00419         }
00420         return iter;
00421     }
00422 
00423     inline OMultiTypeInterfaceContainerHelperVar( const OMultiTypeInterfaceContainerHelperVar & ) SAL_THROW(());
00424     inline OMultiTypeInterfaceContainerHelperVar & operator = ( const OMultiTypeInterfaceContainerHelperVar & ) SAL_THROW(());
00425 };
00426 
00427 
00428 
00429 
00439 template < class container , class keyType >
00440 struct OBroadcastHelperVar
00441 {
00443     ::osl::Mutex &                      rMutex;
00445     container   aLC;
00447     sal_Bool                            bDisposed;
00449     sal_Bool                            bInDispose;
00450 
00455     OBroadcastHelperVar( ::osl::Mutex & rMutex_ ) SAL_THROW(())
00456         : rMutex( rMutex_ )
00457         , aLC( rMutex_ )
00458         , bDisposed( sal_False )
00459         , bInDispose( sal_False )
00460     {}
00461 
00465     inline void addListener(
00466         const keyType &key,
00467         const ::com::sun::star::uno::Reference < ::com::sun::star::uno::XInterface > &r )
00468         SAL_THROW(())
00469     {
00470         ::osl::MutexGuard guard( rMutex );
00471         OSL_ENSURE( !bInDispose, "do not add listeners in the dispose call" );
00472         OSL_ENSURE( !bDisposed, "object is disposed" );
00473         if( ! bInDispose && ! bDisposed  )
00474             aLC.addInterface( key , r );
00475     }
00476 
00480     inline void removeListener(
00481         const keyType &key,
00482         const ::com::sun::star::uno::Reference < ::com::sun::star::uno::XInterface > & r )
00483         SAL_THROW(())
00484     {
00485         ::osl::MutexGuard guard( rMutex );
00486         OSL_ENSURE( !bDisposed, "object is disposed" );
00487         if( ! bInDispose && ! bDisposed  )
00488             aLC.removeInterface( key , r );
00489     }
00490 
00497     inline OInterfaceContainerHelper * SAL_CALL getContainer( const keyType &key ) const SAL_THROW(())
00498         { return aLC.getContainer( key ); }
00499 };
00500 
00501 /*------------------------------------------
00502 *
00503 * In general, the above templates are used with a Type as key.
00504 * Therefore a default declaration is given ( OMultiTypeInterfaceContainerHelper and OBroadcastHelper )
00505 *
00506 *------------------------------------------*/
00507 
00508 // helper function call class
00509 struct hashType_Impl
00510 {
00511     size_t operator()(const ::com::sun::star::uno::Type & s) const SAL_THROW(())
00512     { return (size_t) s.getTypeName().hashCode(); }
00513 };
00514 
00515 
00519 class CPPUHELPER_DLLPUBLIC OMultiTypeInterfaceContainerHelper
00520 {
00521 public:
00522     // these are here to force memory de/allocation to sal lib.
00523     inline static void * SAL_CALL operator new( size_t nSize ) SAL_THROW(())
00524         { return ::rtl_allocateMemory( nSize ); }
00525     inline static void SAL_CALL operator delete( void * pMem ) SAL_THROW(())
00526         { ::rtl_freeMemory( pMem ); }
00527     inline static void * SAL_CALL operator new( size_t, void * pMem ) SAL_THROW(())
00528         { return pMem; }
00529     inline static void SAL_CALL operator delete( void *, void * ) SAL_THROW(())
00530         {}
00531 
00539     OMultiTypeInterfaceContainerHelper( ::osl::Mutex & rMutex ) SAL_THROW(());
00543     ~OMultiTypeInterfaceContainerHelper() SAL_THROW(());
00544 
00548     ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getContainedTypes() const SAL_THROW(());
00549 
00555     OInterfaceContainerHelper * SAL_CALL getContainer( const ::com::sun::star::uno::Type & rKey ) const SAL_THROW(());
00556 
00575     sal_Int32 SAL_CALL addInterface(
00576         const ::com::sun::star::uno::Type & rKey,
00577         const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > & r )
00578         SAL_THROW(());
00579 
00590     sal_Int32 SAL_CALL removeInterface(
00591         const ::com::sun::star::uno::Type & rKey,
00592         const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > & rxIFace )
00593         SAL_THROW(());
00594 
00599     void    SAL_CALL disposeAndClear( const ::com::sun::star::lang::EventObject & rEvt ) SAL_THROW(());
00603     void SAL_CALL clear() SAL_THROW(());
00604 
00605     typedef ::com::sun::star::uno::Type keyType;
00606 private:
00607     void *m_pMap;
00608     ::osl::Mutex &  rMutex;
00609 
00610     inline OMultiTypeInterfaceContainerHelper( const OMultiTypeInterfaceContainerHelper & ) SAL_THROW(());
00611     inline OMultiTypeInterfaceContainerHelper & operator = ( const OMultiTypeInterfaceContainerHelper & ) SAL_THROW(());
00612 };
00613 
00614 typedef OBroadcastHelperVar< OMultiTypeInterfaceContainerHelper , OMultiTypeInterfaceContainerHelper::keyType > OBroadcastHelper;
00615 
00616 }
00617 
00618 #endif
00619 
00620 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines