LibreOffice
LibreOffice 4.4 SDK C/C++ API Reference
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros 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  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 #ifndef INCLUDED_CPPUHELPER_INTERFACECONTAINER_H
20 #define INCLUDED_CPPUHELPER_INTERFACECONTAINER_H
21 
22 #include <sal/config.h>
23 
24 #include <functional>
25 #include <vector>
26 #include <utility>
27 
28 #include <osl/diagnose.h>
29 #include <osl/mutex.hxx>
30 #include <rtl/alloc.h>
32 #include <com/sun/star/uno/XInterface.hpp>
33 #include <com/sun/star/lang/EventObject.hpp>
34 
35 #include <com/sun/star/lang/DisposedException.hpp>
37  //for docpp
39 namespace cppu
40 {
41 
42 namespace detail {
43 
45  {
47  ::com::sun::star::uno::XInterface * pAsInterface;
49  };
50 
51 }
52 
53 
54 class OInterfaceContainerHelper;
63 {
64 public:
79 
84 
86  bool SAL_CALL hasMoreElements() const
87  { return nRemain != 0; }
92  ::com::sun::star::uno::XInterface * SAL_CALL next();
93 
99  void SAL_CALL remove();
100 
101 private:
103  sal_Bool bIsList;
104 
105  detail::element_alias aData;
106 
107  sal_Int32 nRemain;
108 
110  OInterfaceIteratorHelper & operator = ( const OInterfaceIteratorHelper & );
111 };
112 
113 
121 {
122 public:
123  // these are here to force memory de/allocation to sal lib.
124  inline static void * SAL_CALL operator new( size_t nSize )
125  { return ::rtl_allocateMemory( nSize ); }
126  inline static void SAL_CALL operator delete( void * pMem )
127  { ::rtl_freeMemory( pMem ); }
128  inline static void * SAL_CALL operator new( size_t, void * pMem )
129  { return pMem; }
130  inline static void SAL_CALL operator delete( void *, void * )
131  {}
132 
150  sal_Int32 SAL_CALL getLength() const;
151 
156 
173  sal_Int32 SAL_CALL addInterface( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > & rxIFace );
181  sal_Int32 SAL_CALL removeInterface( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > & rxIFace );
186  void SAL_CALL disposeAndClear( const ::com::sun::star::lang::EventObject & rEvt );
190  void SAL_CALL clear();
191 
203  template <typename ListenerT, typename FuncT>
204  inline void forEach( FuncT const& func );
205 
227  template< typename ListenerT, typename EventT >
228  inline void notifyEach( void ( SAL_CALL ListenerT::*NotificationMethod )( const EventT& ), const EventT& Event );
229 
230 private:
236  detail::element_alias aData;
237  ::osl::Mutex & rMutex;
239  sal_Bool bInUse;
241  sal_Bool bIsList;
242 
244  OInterfaceContainerHelper & operator = ( const OInterfaceContainerHelper & );
245 
246  /*
247  Dulicate content of the conaitner and release the old one without destroying.
248  The mutex must be locked and the memberbInUse must be true.
249  */
250  void copyAndResetInUse();
251 
252 private:
253  template< typename ListenerT, typename EventT >
254  class NotifySingleListener
255  {
256  private:
257  typedef void ( SAL_CALL ListenerT::*NotificationMethod )( const EventT& );
258  NotificationMethod m_pMethod;
259  const EventT& m_rEvent;
260  public:
261  NotifySingleListener( NotificationMethod method, const EventT& event ) : m_pMethod( method ), m_rEvent( event ) { }
262 
263  void operator()( const ::com::sun::star::uno::Reference<ListenerT>& listener ) const
264  {
265  (listener.get()->*m_pMethod)( m_rEvent );
266  }
267  };
268 };
269 
270 template <typename ListenerT, typename FuncT>
271 inline void OInterfaceContainerHelper::forEach( FuncT const& func )
272 {
273  OInterfaceIteratorHelper iter( *this );
274  while (iter.hasMoreElements()) {
277  if (xListener.is()) {
278  try {
279  func( xListener );
280  }
281  catch (::com::sun::star::lang::DisposedException const& exc) {
282  if (exc.Context == xListener)
283  iter.remove();
284  }
285  }
286  }
287 }
288 
289 template< typename ListenerT, typename EventT >
290 inline void OInterfaceContainerHelper::notifyEach( void ( SAL_CALL ListenerT::*NotificationMethod )( const EventT& ), const EventT& Event )
291 {
292  forEach< ListenerT, NotifySingleListener< ListenerT, EventT > >( NotifySingleListener< ListenerT, EventT >( NotificationMethod, Event ) );
293 }
294 
295 
302 template< class key, class hashImpl = void, class equalImpl = std::equal_to<key> >
304 {
305 public:
306  // these are here to force memory de/allocation to sal lib.
307  inline static void * SAL_CALL operator new( size_t nSize )
308  { return ::rtl_allocateMemory( nSize ); }
309  inline static void SAL_CALL operator delete( void * pMem )
310  { ::rtl_freeMemory( pMem ); }
311  inline static void * SAL_CALL operator new( size_t, void * pMem )
312  { return pMem; }
313  inline static void SAL_CALL operator delete( void *, void * )
314  {}
315 
328 
332  inline ::com::sun::star::uno::Sequence< key > SAL_CALL getContainedTypes() const;
333 
340  inline OInterfaceContainerHelper * SAL_CALL getContainer( const key & ) const;
341 
360  inline sal_Int32 SAL_CALL addInterface(
361  const key & rKey,
362  const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > & r );
363 
374  inline sal_Int32 SAL_CALL removeInterface(
375  const key & rKey,
376  const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > & rxIFace );
377 
383  inline void SAL_CALL disposeAndClear( const ::com::sun::star::lang::EventObject & rEvt );
387  inline void SAL_CALL clear();
388 
389  typedef key keyType;
390 private:
391  typedef ::std::vector< std::pair < key , void* > > InterfaceMap;
392  InterfaceMap *m_pMap;
393  ::osl::Mutex & rMutex;
394 
395  inline typename InterfaceMap::iterator find(const key &rKey) const
396  {
397  typename InterfaceMap::iterator iter = m_pMap->begin();
398  typename InterfaceMap::iterator end = m_pMap->end();
399 
400  while( iter != end )
401  {
402  equalImpl equal;
403  if( equal( iter->first, rKey ) )
404  break;
405  iter++;
406  }
407  return iter;
408  }
409 
412 };
413 
414 
415 
416 
426 template < class container , class keyType >
428 {
432  container aLC;
437 
443  : rMutex( rMutex_ )
444  , aLC( rMutex_ )
445  , bDisposed( sal_False )
446  , bInDispose( sal_False )
447  {}
448 
452  inline void addListener(
453  const keyType &key,
454  const ::com::sun::star::uno::Reference < ::com::sun::star::uno::XInterface > &r )
455  {
456  ::osl::MutexGuard guard( rMutex );
457  OSL_ENSURE( !bInDispose, "do not add listeners in the dispose call" );
458  OSL_ENSURE( !bDisposed, "object is disposed" );
459  if( ! bInDispose && ! bDisposed )
460  aLC.addInterface( key , r );
461  }
462 
466  inline void removeListener(
467  const keyType &key,
468  const ::com::sun::star::uno::Reference < ::com::sun::star::uno::XInterface > & r )
469  {
470  ::osl::MutexGuard guard( rMutex );
471  OSL_ENSURE( !bDisposed, "object is disposed" );
472  if( ! bInDispose && ! bDisposed )
473  aLC.removeInterface( key , r );
474  }
475 
482  inline OInterfaceContainerHelper * SAL_CALL getContainer( const keyType &key ) const
483  { return aLC.getContainer( key ); }
484 };
485 
486 /*------------------------------------------
487 *
488 * In general, the above templates are used with a Type as key.
489 * Therefore a default declaration is given ( OMultiTypeInterfaceContainerHelper and OBroadcastHelper )
490 *
491 *------------------------------------------*/
492 
493 // helper function call class
495 {
496  size_t operator()(const ::com::sun::star::uno::Type & s) const
497  { return (size_t) s.getTypeName().hashCode(); }
498 };
499 
500 
505 {
506 public:
507  // these are here to force memory de/allocation to sal lib.
508  inline static void * SAL_CALL operator new( size_t nSize )
509  { return ::rtl_allocateMemory( nSize ); }
510  inline static void SAL_CALL operator delete( void * pMem )
511  { ::rtl_freeMemory( pMem ); }
512  inline static void * SAL_CALL operator new( size_t, void * pMem )
513  { return pMem; }
514  inline static void SAL_CALL operator delete( void *, void * )
515  {}
516 
529 
533  ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getContainedTypes() const;
534 
540  OInterfaceContainerHelper * SAL_CALL getContainer( const ::com::sun::star::uno::Type & rKey ) const;
541 
560  sal_Int32 SAL_CALL addInterface(
561  const ::com::sun::star::uno::Type & rKey,
562  const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > & r );
563 
574  sal_Int32 SAL_CALL removeInterface(
575  const ::com::sun::star::uno::Type & rKey,
576  const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > & rxIFace );
577 
582  void SAL_CALL disposeAndClear( const ::com::sun::star::lang::EventObject & rEvt );
586  void SAL_CALL clear();
587 
588  typedef ::com::sun::star::uno::Type keyType;
589 private:
590  void *m_pMap;
591  ::osl::Mutex & rMutex;
592 
595 };
596 
598 
599 }
600 
601 #endif
602 
603 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */