AlterOffice
AlterOffice 3.4 SDK C/C++ API Reference
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
interfacecontainer.h
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 
3 #ifndef INCLUDED_CPPUHELPER_INTERFACECONTAINER_H
4 #define INCLUDED_CPPUHELPER_INTERFACECONTAINER_H
5 
6 #include "sal/config.h"
7 
8 #include <cstddef>
9 #include <functional>
10 #include <vector>
11 #include <utility>
12 
13 #include "osl/diagnose.h"
14 #include "osl/mutex.hxx"
15 #include "rtl/alloc.h"
17 #include "com/sun/star/lang/EventObject.hpp"
18 
19 #include "com/sun/star/lang/DisposedException.hpp"
21 
22 namespace com { namespace sun { namespace star { namespace uno { class XInterface; } } } }
23 
24 namespace cppu
25 {
26 
27 namespace detail {
28 
34  {
35  std::vector< css::uno::Reference< css::uno::XInterface > > *pAsVector;
36  css::uno::XInterface * pAsInterface;
38  };
39 
40 }
41 
42 
43 class OInterfaceContainerHelper;
52 {
53 public:
68 
73 
75  bool SAL_CALL hasMoreElements() const
76  { return nRemain != 0; }
81  css::uno::XInterface * SAL_CALL next();
82 
88  void SAL_CALL remove();
89 
90 private:
92  sal_Bool bIsList;
93 
95 
96  sal_Int32 nRemain;
97 
100  OInterfaceIteratorHelper & operator = ( const OInterfaceIteratorHelper & )
101  SAL_DELETED_FUNCTION;
102 };
103 
104 
112 {
113 public:
114  // these are here to force memory de/allocation to sal lib.
115  static void * SAL_CALL operator new( size_t nSize )
116  { return ::rtl_allocateMemory( nSize ); }
117  static void SAL_CALL operator delete( void * pMem )
118  { ::rtl_freeMemory( pMem ); }
119  static void * SAL_CALL operator new( size_t, void * pMem )
120  { return pMem; }
121  static void SAL_CALL operator delete( void *, void * )
122  {}
123 
131  OInterfaceContainerHelper( ::osl::Mutex & rMutex );
136  ~OInterfaceContainerHelper();
141  sal_Int32 SAL_CALL getLength() const;
142 
146  css::uno::Sequence< css::uno::Reference< css::uno::XInterface > > SAL_CALL getElements() const;
147 
164  sal_Int32 SAL_CALL addInterface( const css::uno::Reference< css::uno::XInterface > & rxIFace );
172  sal_Int32 SAL_CALL removeInterface( const css::uno::Reference< css::uno::XInterface > & rxIFace );
177  void SAL_CALL disposeAndClear( const css::lang::EventObject & rEvt );
181  void SAL_CALL clear();
182 
194  template <typename ListenerT, typename FuncT>
195  inline void forEach( FuncT const& func );
196 
218  template< typename ListenerT, typename EventT >
219  inline void notifyEach( void ( SAL_CALL ListenerT::*NotificationMethod )( const EventT& ), const EventT& Event );
220 
221 private:
227  detail::element_alias aData;
228  ::osl::Mutex & rMutex;
230  sal_Bool bInUse;
232  sal_Bool bIsList;
233 
234  OInterfaceContainerHelper( const OInterfaceContainerHelper & )
235  SAL_DELETED_FUNCTION;
236  OInterfaceContainerHelper & operator = ( const OInterfaceContainerHelper & )
237  SAL_DELETED_FUNCTION;
238 
239  /*
240  Duplicate content of the container and release the old one without destroying.
241  The mutex must be locked and the memberbInUse must be true.
242  */
243  void copyAndResetInUse();
244 
245 private:
246  template< typename ListenerT, typename EventT >
247  class NotifySingleListener
248  {
249  private:
250  typedef void ( SAL_CALL ListenerT::*NotificationMethod )( const EventT& );
251  NotificationMethod m_pMethod;
252  const EventT& m_rEvent;
253  public:
254  NotifySingleListener( NotificationMethod method, const EventT& event ) : m_pMethod( method ), m_rEvent( event ) { }
255 
256  void operator()( const css::uno::Reference<ListenerT>& listener ) const
257  {
258  (listener.get()->*m_pMethod)( m_rEvent );
259  }
260  };
261 };
262 
263 template <typename ListenerT, typename FuncT>
264 inline void OInterfaceContainerHelper::forEach( FuncT const& func )
265 {
266  OInterfaceIteratorHelper iter( *this );
267  while (iter.hasMoreElements()) {
268  css::uno::Reference<ListenerT> const xListener( iter.next(), css::uno::UNO_QUERY );
269  if (xListener.is()) {
270  try {
271  func( xListener );
272  }
273  catch (css::lang::DisposedException const& exc) {
274  if (exc.Context == xListener)
275  iter.remove();
276  }
277  }
278  }
279 }
280 
281 template< typename ListenerT, typename EventT >
282 inline void OInterfaceContainerHelper::notifyEach( void ( SAL_CALL ListenerT::*NotificationMethod )( const EventT& ), const EventT& Event )
283 {
284  forEach< ListenerT, NotifySingleListener< ListenerT, EventT > >( NotifySingleListener< ListenerT, EventT >( NotificationMethod, Event ) );
285 }
286 
287 
294 template< class key, class hashImpl = void, class equalImpl = std::equal_to<key> >
296 {
297 public:
298  // these are here to force memory de/allocation to sal lib.
299  static void * SAL_CALL operator new( size_t nSize )
300  { return ::rtl_allocateMemory( nSize ); }
301  static void SAL_CALL operator delete( void * pMem )
302  { ::rtl_freeMemory( pMem ); }
303  static void * SAL_CALL operator new( size_t, void * pMem )
304  { return pMem; }
305  static void SAL_CALL operator delete( void *, void * )
306  {}
307 
320 
324  inline css::uno::Sequence< key > SAL_CALL getContainedTypes() const;
325 
332  inline OInterfaceContainerHelper * SAL_CALL getContainer( const key & ) const;
333 
352  inline sal_Int32 SAL_CALL addInterface(
353  const key & rKey,
354  const css::uno::Reference< css::uno::XInterface > & r );
355 
366  inline sal_Int32 SAL_CALL removeInterface(
367  const key & rKey,
368  const css::uno::Reference< css::uno::XInterface > & rxIFace );
369 
375  inline void SAL_CALL disposeAndClear( const css::lang::EventObject & rEvt );
379  inline void SAL_CALL clear();
380 
381  typedef key keyType;
382 private:
383  typedef ::std::vector< std::pair < key , void* > > InterfaceMap;
384  InterfaceMap *m_pMap;
385  ::osl::Mutex & rMutex;
386 
387  typename InterfaceMap::iterator find(const key &rKey) const
388  {
389  typename InterfaceMap::iterator iter = m_pMap->begin();
390  typename InterfaceMap::iterator end = m_pMap->end();
391 
392  while( iter != end )
393  {
394  equalImpl equal;
395  if( equal( iter->first, rKey ) )
396  break;
397  ++iter;
398  }
399  return iter;
400  }
401 
403  OMultiTypeInterfaceContainerHelperVar & operator = ( const OMultiTypeInterfaceContainerHelperVar & ) SAL_DELETED_FUNCTION;
404 };
405 
406 
407 
408 
418 template < class container , class keyType >
420 {
424  container aLC;
429 
435  : rMutex( rMutex_ )
436  , aLC( rMutex_ )
437  , bDisposed( false )
438  , bInDispose( false )
439  {}
440 
445  const keyType &key,
446  const css::uno::Reference < css::uno::XInterface > &r )
447  {
448  ::osl::MutexGuard guard( rMutex );
449  OSL_ENSURE( !bInDispose, "do not add listeners in the dispose call" );
450  OSL_ENSURE( !bDisposed, "object is disposed" );
451  if( ! bInDispose && ! bDisposed )
452  aLC.addInterface( key , r );
453  }
454 
459  const keyType &key,
460  const css::uno::Reference < css::uno::XInterface > & r )
461  {
462  ::osl::MutexGuard guard( rMutex );
463  if( ! bInDispose && ! bDisposed )
464  aLC.removeInterface( key , r );
465  }
466 
473  OInterfaceContainerHelper * SAL_CALL getContainer( const keyType &key ) const
474  { return aLC.getContainer( key ); }
475 };
476 
477 /*------------------------------------------
478 *
479 * In general, the above templates are used with a Type as key.
480 * Therefore a default declaration is given ( OMultiTypeInterfaceContainerHelper and OBroadcastHelper )
481 *
482 *------------------------------------------*/
483 
484 // helper function call class
486 {
487  size_t operator()(const css::uno::Type & s) const
488  { return static_cast<size_t>(s.getTypeName().hashCode()); }
489 };
490 
491 
496 {
497 public:
498  // these are here to force memory de/allocation to sal lib.
499  static void * SAL_CALL operator new( size_t nSize )
500  { return ::rtl_allocateMemory( nSize ); }
501  static void SAL_CALL operator delete( void * pMem )
502  { ::rtl_freeMemory( pMem ); }
503  static void * SAL_CALL operator new( size_t, void * pMem )
504  { return pMem; }
505  static void SAL_CALL operator delete( void *, void * )
506  {}
507 
520 
524  css::uno::Sequence< css::uno::Type > SAL_CALL getContainedTypes() const;
525 
531  OInterfaceContainerHelper * SAL_CALL getContainer( const css::uno::Type & rKey ) const;
532 
551  sal_Int32 SAL_CALL addInterface(
552  const css::uno::Type & rKey,
553  const css::uno::Reference< css::uno::XInterface > & r );
554 
565  sal_Int32 SAL_CALL removeInterface(
566  const css::uno::Type & rKey,
567  const css::uno::Reference< css::uno::XInterface > & rxIFace );
568 
573  void SAL_CALL disposeAndClear( const css::lang::EventObject & rEvt );
577  void SAL_CALL clear();
578 
579  typedef css::uno::Type keyType;
580 private:
581  void * m_pMap;
582  ::osl::Mutex & rMutex;
583 
585  OMultiTypeInterfaceContainerHelper & operator = ( const OMultiTypeInterfaceContainerHelper & ) SAL_DELETED_FUNCTION;
586 };
587 
588 typedef OBroadcastHelperVar< OMultiTypeInterfaceContainerHelper , OMultiTypeInterfaceContainerHelper::keyType > OBroadcastHelper;
589 
590 }
591 
592 #endif
593 
594 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Definition: interfacecontainer.h:485
unsigned char sal_Bool
Definition: types.h:18
SAL_DLLPUBLIC void rtl_freeMemory(void *Ptr) SAL_THROW_EXTERN_C()
Free memory.
OBroadcastHelperVar(::osl::Mutex &rMutex_)
Initialize the structure.
Definition: interfacecontainer.h:434
css::uno::Type keyType
Definition: interfacecontainer.h:579
css::uno::XInterface * next()
Return the next element of the iterator.
std::vector< css::uno::Reference< css::uno::XInterface > > * pAsVector
Definition: interfacecontainer.h:35
sal_Bool bDisposed
Dispose call ready.
Definition: interfacecontainer.h:426
::osl::Mutex & rMutex
The shared mutex.
Definition: interfacecontainer.h:422
This enum value can be used for implicit interface query.
Definition: Reference.h:137
element_alias()
Definition: interfacecontainer.h:37
#define SAL_WARN_UNUSED
Annotate classes where a compiler should warn if an instance is unused.
Definition: types.h:567
size_t operator()(const css::uno::Type &s) const
Definition: interfacecontainer.h:487
#define CPPUHELPER_DLLPUBLIC
Definition: cppuhelperdllapi.h:12
void remove()
Removes the current element (the last one returned by next()) from the underlying container...
void notifyEach(void(ListenerT::*NotificationMethod)(const EventT &), const EventT &Event)
Calls a UNO listener method for each contained listener.
Definition: interfacecontainer.h:282
container aLC
ListenerContainer class is thread safe.
Definition: interfacecontainer.h:424
#define OSL_ENSURE(c, m)
If cond is false, reports an error with message msg.
Definition: diagnose.h:67
OInterfaceContainerHelper * getContainer(const keyType &key) const
Return the container created under this key.
Definition: interfacecontainer.h:473
Specialized class for key type css::uno::Type, without explicit usage of STL symbols.
Definition: interfacecontainer.h:495
A container of interfaces.
Definition: interfacecontainer.h:111
This is here to optimise space in the common case that there are zero or one listeners.
Definition: interfacecontainer.h:33
A mutual exclusion synchronization object.
Definition: mutex.hxx:15
void removeListener(const keyType &key, const css::uno::Reference< css::uno::XInterface > &r)
removes a listener threadsafe
Definition: interfacecontainer.h:458
void addListener(const keyType &key, const css::uno::Reference< css::uno::XInterface > &r)
adds a listener threadsafe.
Definition: interfacecontainer.h:444
Provides simple diagnostic support.
This is the iterator of an InterfaceContainerHelper.
Definition: interfacecontainer.h:51
SAL_DLLPUBLIC void * rtl_allocateMemory(sal_Size Bytes) SAL_THROW_EXTERN_C()
Allocate memory.
Object lifetime scoped mutex object or interface lock.
Definition: mutex.hxx:103
bool hasMoreElements() const
Return true, if there are more elements in the iterator.
Definition: interfacecontainer.h:75
sal_Bool bInDispose
In dispose call.
Definition: interfacecontainer.h:428
This struct contains the standard variables of a broadcaster.
Definition: interfacecontainer.h:419
void forEach(FuncT const &func)
Executes a functor for each contained listener of specified type, e.g.
Definition: interfacecontainer.h:264
css::uno::XInterface * pAsInterface
Definition: interfacecontainer.h:36
key keyType
Definition: interfacecontainer.h:381
#define SAL_DELETED_FUNCTION
short-circuit extra-verbose API namespaces
Definition: types.h:358
A helper class to store interface references of different types.
Definition: interfacecontainer.h:295