LCOV - code coverage report
Current view: top level - include/comphelper - servicedecl.hxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 34 38 89.5 %
Date: 2014-11-03 Functions: 324 649 49.9 %
Legend: Lines: hit not hit

          Line data    Source code
       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_COMPHELPER_SERVICEDECL_HXX
      20             : #define INCLUDED_COMPHELPER_SERVICEDECL_HXX
      21             : 
      22             : #include <comphelper/comphelperdllapi.h>
      23             : #include <cppuhelper/implbase1.hxx>
      24             : #include <com/sun/star/uno/XComponentContext.hpp>
      25             : #include <com/sun/star/lang/XServiceInfo.hpp>
      26             : #include <com/sun/star/registry/XRegistryKey.hpp>
      27             : #include <uno/environment.h>
      28             : #include <boost/utility.hpp>
      29             : #include <boost/function.hpp>
      30             : #include <boost/preprocessor/cat.hpp>
      31             : #include <boost/preprocessor/repetition.hpp>
      32             : #include <boost/preprocessor/seq/enum.hpp>
      33             : 
      34             : namespace comphelper {
      35             : namespace service_decl {
      36             : 
      37             : class ServiceDecl;
      38             : 
      39             : namespace detail {
      40             : typedef ::boost::function3<
      41             :     css::uno::Reference<css::uno::XInterface> /* return */,
      42             :     ServiceDecl const&,
      43             :     css::uno::Sequence<css::uno::Any> const&,
      44             :     css::uno::Reference<css::uno::XComponentContext> const&> CreateFuncF;
      45             : }
      46             : 
      47             : /** Class to declare a service implementation.  There is no need to implement
      48             :     lang::XServiceInfo nor lang::XInitialization anymore.
      49             :     The declaration can be done in various ways, the (simplest) form is
      50             : 
      51             :     <pre>
      52             :     class MyClass : public cppu::WeakImplHelper2<XInterface1, XInterface2> {
      53             :     public:
      54             :         MyClass( uno::Reference<uno::XComponentContext> const& xContext )
      55             :         [...]
      56             :     };
      57             :     [...]
      58             :     namespace sdecl = comphelper::service_decl;
      59             :     sdecl::ServiceDecl const myDecl(
      60             :         sdecl::class_<MyClass>(),
      61             :         "my.unique.implementation.name",
      62             :         "MyServiceSpec1;MyServiceSpec2" );
      63             :     </pre>
      64             : 
      65             :     If the service demands initialization by arguments, the implementation
      66             :     class has to define a constructor taking both arguments and component
      67             :     context:
      68             : 
      69             :     <pre>
      70             :     class MyClass : public cppu::WeakImplHelper2<XInterface1, XInterface2> {
      71             :     public:
      72             :         MyClass( uno::Sequence<uno::Any> const& args,
      73             :                  uno::Reference<uno:XComponentContext> const& xContext )
      74             :         [...]
      75             :     };
      76             :     [...]
      77             :     namespace sdecl = comphelper::service_decl;
      78             :     sdecl::ServiceDecl const myDecl(
      79             :         sdecl::class_<MyClass, sdecl::with_args<true> >(),
      80             :         "my.unique.implementation.name",
      81             :         "MyServiceSpec1;MyServiceSpec2" );
      82             :     </pre>
      83             : 
      84             :     Additionally, there is the possibility to process some code after creation,
      85             :     e.g. to add the newly created object as a listener or perform aggregation
      86             :     (C++-UNO only):
      87             : 
      88             :     <pre>
      89             :     uno::Reference<uno::XInterface> somePostProcCode( MyClass * p );
      90             :     [...]
      91             :     namespace sdecl = comphelper::service_decl;
      92             :     sdecl::ServiceDecl const myDecl(
      93             :         sdecl::class_<MyClass, ... >(&somePostProcCode),
      94             :         "my.unique.implementation.name",
      95             :         "MyServiceSpec1;MyServiceSpec2" );
      96             :     </pre>
      97             : 
      98             :     In the latter case, somePostProcCode gets the yet unacquired "raw" pointer.
      99             : */
     100        1318 : class COMPHELPER_DLLPUBLIC ServiceDecl : private ::boost::noncopyable
     101             : {
     102             : public:
     103             :     /** Ctor for multiple supported service names.
     104             : 
     105             :         @param implClass implementation class description
     106             :         @param pImplName implementation name
     107             :         @param pSupportedServiceNames supported service names
     108             :         @param cDelim delimiter for supported service names
     109             :     */
     110             :     template <typename ImplClassT>
     111        1460 :     ServiceDecl( ImplClassT const& implClass,
     112             :                  char const* pImplName,
     113             :                  char const* pSupportedServiceNames, char cDelim = ';' )
     114             :         : m_createFunc(implClass.m_createFunc),
     115             :           m_pImplName(pImplName),
     116             :           m_pServiceNames(pSupportedServiceNames),
     117        1460 :           m_cDelim(cDelim) {}
     118             : 
     119             :     /// @internal gets called by component_getFactoryHelper()
     120             :     void * getFactory( sal_Char const* pImplName ) const;
     121             : 
     122             :     /// @return supported service names
     123             :     ::com::sun::star::uno::Sequence< OUString>
     124             :     getSupportedServiceNames() const;
     125             : 
     126             :     /// @return whether name is in set of supported service names
     127             :     bool supportsService( OUString const& name ) const;
     128             : 
     129             :     /// @return implementation name
     130             :     OUString getImplementationName() const;
     131             : 
     132             : private:
     133             :     class Factory;
     134             :     friend class Factory;
     135             : 
     136             :     detail::CreateFuncF const m_createFunc;
     137             :     char const* const m_pImplName;
     138             :     char const* const m_pServiceNames;
     139             :     char const m_cDelim;
     140             : };
     141             : 
     142             : /** To specify whether the implementation class expects arguments
     143             :     (uno::Sequence<uno::Any>).
     144             : */
     145             : template <bool> struct with_args;
     146             : 
     147             : /// @internal
     148             : namespace detail {
     149             : template <typename ImplT>
     150        3616 : class OwnServiceImpl
     151             :     : public ImplT,
     152             :       private ::boost::noncopyable
     153             : {
     154             :     typedef ImplT BaseT;
     155             : 
     156             : public:
     157        3374 :     OwnServiceImpl(
     158             :         ServiceDecl const& rServiceDecl,
     159             :         css::uno::Sequence<css::uno::Any> const& args,
     160             :         css::uno::Reference<css::uno::XComponentContext> const& xContext )
     161        3374 :         :BaseT(args, xContext), m_rServiceDecl(rServiceDecl) {}
     162         414 :     OwnServiceImpl(
     163             :         ServiceDecl const& rServiceDecl,
     164             :         css::uno::Reference<css::uno::XComponentContext> const& xContext )
     165         414 :         : BaseT(xContext), m_rServiceDecl(rServiceDecl) {}
     166             : 
     167             :     // XServiceInfo
     168           0 :     virtual OUString SAL_CALL getImplementationName()
     169             :         throw (css::uno::RuntimeException) SAL_OVERRIDE {
     170           0 :         return m_rServiceDecl.getImplementationName();
     171             :     }
     172         260 :     virtual sal_Bool SAL_CALL supportsService( OUString const& name )
     173             :         throw (css::uno::RuntimeException) SAL_OVERRIDE {
     174         260 :         return m_rServiceDecl.supportsService(name);
     175             :     }
     176             :     virtual css::uno::Sequence< OUString>
     177           0 :     SAL_CALL getSupportedServiceNames() throw (css::uno::RuntimeException) SAL_OVERRIDE {
     178           0 :         return m_rServiceDecl.getSupportedServiceNames();
     179             :     }
     180             : 
     181             : private:
     182             :     ServiceDecl const& m_rServiceDecl;
     183             : };
     184             : 
     185             : template <typename ImplT>
     186        7056 : class ServiceImpl : public OwnServiceImpl< ::cppu::ImplInheritanceHelper1<ImplT,css::lang::XServiceInfo> >
     187             : {
     188             : typedef OwnServiceImpl< ::cppu::ImplInheritanceHelper1<ImplT,css::lang::XServiceInfo> > ServiceImpl_BASE;
     189             : public:
     190        3124 :     ServiceImpl(
     191             :         ServiceDecl const& rServiceDecl,
     192             :         css::uno::Sequence<css::uno::Any> const& args,
     193             :         css::uno::Reference<css::uno::XComponentContext> const& xContext )
     194        3124 :         : ServiceImpl_BASE(rServiceDecl, args, xContext) {}
     195         414 :     ServiceImpl(
     196             :         ServiceDecl const& rServiceDecl,
     197             :         css::uno::Reference<css::uno::XComponentContext> const& xContext )
     198         414 :         : ServiceImpl_BASE(rServiceDecl, xContext) {}
     199             : };
     200             : 
     201             : template <typename ServiceImplT>
     202             : struct PostProcessDefault {
     203             :     css::uno::Reference<css::uno::XInterface>
     204        3784 :     operator()( ServiceImplT * p ) const {
     205        3784 :         return static_cast<css::lang::XServiceInfo *>(p);
     206             :     }
     207             : };
     208             : 
     209             : template <typename ImplT, typename PostProcessFuncT, typename WithArgsT>
     210             : struct CreateFunc;
     211             : 
     212             : template <typename ImplT, typename PostProcessFuncT>
     213             : struct CreateFunc<ImplT, PostProcessFuncT, with_args<false> > {
     214             :     PostProcessFuncT const m_postProcessFunc;
     215         436 :     explicit CreateFunc( PostProcessFuncT const& postProcessFunc )
     216         436 :         : m_postProcessFunc(postProcessFunc) {}
     217             : 
     218             :     css::uno::Reference<css::uno::XInterface>
     219         414 :     operator()( ServiceDecl const& rServiceDecl,
     220             :                 css::uno::Sequence<css::uno::Any> const&,
     221             :                 css::uno::Reference<css::uno::XComponentContext>
     222             :                 const& xContext ) const
     223             :     {
     224             :         return m_postProcessFunc(
     225         414 :             new ImplT( rServiceDecl, xContext ) );
     226             :     }
     227             : };
     228             : 
     229             : template <typename ImplT, typename PostProcessFuncT>
     230             : struct CreateFunc<ImplT, PostProcessFuncT, with_args<true> > {
     231             :     PostProcessFuncT const m_postProcessFunc;
     232        1024 :     explicit CreateFunc( PostProcessFuncT const& postProcessFunc )
     233        1024 :         : m_postProcessFunc(postProcessFunc) {}
     234             : 
     235             :     css::uno::Reference<css::uno::XInterface>
     236        3374 :     operator()( ServiceDecl const& rServiceDecl,
     237             :                 css::uno::Sequence<css::uno::Any> const& args,
     238             :                 css::uno::Reference<css::uno::XComponentContext>
     239             :                 const& xContext ) const
     240             :     {
     241             :         return m_postProcessFunc(
     242        3374 :             new ImplT( rServiceDecl, args, xContext ) );
     243             :     }
     244             : };
     245             : 
     246             : } // namespace detail
     247             : 
     248             : /** Defines a service implementation class.
     249             : 
     250             :     @tpl ImplT_ service implementation class
     251             :     @WithArgsT whether the implementation class ctor expects arguments
     252             :                (uno::Sequence<uno::Any>, uno::Reference<uno::XComponentContext>)
     253             :                or just (uno::Reference<uno::XComponentContext>)
     254             : */
     255             : template <typename ImplT_, typename WithArgsT = with_args<false> >
     256        1320 : struct serviceimpl_base {
     257             :     typedef ImplT_ ImplT;
     258             : 
     259             :     detail::CreateFuncF const m_createFunc;
     260             : 
     261             :     typedef detail::PostProcessDefault<ImplT> PostProcessDefaultT;
     262             : 
     263             :     /** Default ctor.  Implementation class without args, expecting
     264             :         component context as single argument.
     265             :     */
     266        1456 :     serviceimpl_base() : m_createFunc(
     267             :         detail::CreateFunc<ImplT, PostProcessDefaultT, WithArgsT>(
     268        1456 :             PostProcessDefaultT() ) ) {}
     269             : 
     270             :     /** Ctor to pass a post processing function/functor.
     271             : 
     272             :         @tpl PostProcessDefaultT let your compiler deduce this
     273             :         @param postProcessFunc function/functor that gets the yet unacquired
     274             :                                ImplT_ pointer returning a
     275             :                                uno::Reference<uno::XInterface>
     276             :     */
     277             :     template <typename PostProcessFuncT>
     278           4 :     explicit serviceimpl_base( PostProcessFuncT const& postProcessFunc )
     279             :         : m_createFunc( detail::CreateFunc<ImplT, PostProcessFuncT, WithArgsT>(
     280           4 :                             postProcessFunc ) ) {}
     281             : };
     282             : 
     283             : template <typename ImplT_, typename WithArgsT = with_args<false> >
     284        1288 : struct class_ : public serviceimpl_base< detail::ServiceImpl<ImplT_>, WithArgsT >
     285             : {
     286             :     typedef serviceimpl_base< detail::ServiceImpl<ImplT_>, WithArgsT > baseT;
     287             :     /** Default ctor.  Implementation class without args, expecting
     288             :         component context as single argument.
     289             :     */
     290        1424 :     class_() : baseT() {}
     291             :     template <typename PostProcessFuncT>
     292             :     /** Ctor to pass a post processing function/functor.
     293             : 
     294             :         @tpl PostProcessDefaultT let your compiler deduce this
     295             :         @param postProcessFunc function/functor that gets the yet unacquired
     296             :                                ImplT_ pointer returning a
     297             :                                uno::Reference<uno::XInterface>
     298             :     */
     299           4 :     explicit class_( PostProcessFuncT const& postProcessFunc ) : baseT( postProcessFunc ) {}
     300             : };
     301             : 
     302             : 
     303             : // component_... helpers with arbitrary service declarations:
     304             : 
     305             : 
     306             : #define COMPHELPER_SERVICEDECL_getFactory(z_, n_, unused_) \
     307             :     if (pRet == 0) \
     308             :         pRet = BOOST_PP_CAT(s, n_).getFactory(pImplName);
     309             : 
     310             : /** The following preprocessor repetitions generate functions like
     311             : 
     312             :     <pre>
     313             :         inline void * component_getFactoryHelper(
     314             :             sal_Char const* pImplName,
     315             :             ::com::sun::star::lang::XMultiServiceFactory *,
     316             :             ::com::sun::star::registry::XRegistryKey * xRegistryKey,
     317             :             ServiceDecl const& s0, ServiceDecl const& s1, ... );
     318             :     </pre>
     319             : 
     320             :     which call on the passed service declarations.
     321             : 
     322             :     The maximum number of service declarations can be set by defining
     323             :     COMPHELPER_SERVICEDECL_COMPONENT_HELPER_MAX_ARGS; its default is 8.
     324             : */
     325             : #define COMPHELPER_SERVICEDECL_make(z_, n_, unused_) \
     326             : inline void * component_getFactoryHelper( \
     327             :     sal_Char const* pImplName, \
     328             :     ::com::sun::star::lang::XMultiServiceFactory *, \
     329             :     ::com::sun::star::registry::XRegistryKey *, \
     330             :     BOOST_PP_ENUM_PARAMS(n_, ServiceDecl const& s) ) \
     331             : { \
     332             :     void * pRet = 0; \
     333             :     BOOST_PP_REPEAT(n_, COMPHELPER_SERVICEDECL_getFactory, ~) \
     334             :     return pRet; \
     335             : }
     336             : 
     337             : #ifndef COMPHELPER_SERVICEDECL_COMPONENT_HELPER_MAX_ARGS
     338             : #define COMPHELPER_SERVICEDECL_COMPONENT_HELPER_MAX_ARGS 8
     339             : #endif
     340             : 
     341        1152 : BOOST_PP_REPEAT_FROM_TO(1, COMPHELPER_SERVICEDECL_COMPONENT_HELPER_MAX_ARGS,
     342             :                         COMPHELPER_SERVICEDECL_make, ~)
     343             : 
     344             : #undef COMPHELPER_SERVICEDECL_COMPONENT_HELPER_MAX_ARGS
     345             : #undef COMPHELPER_SERVICEDECL_make
     346             : #undef COMPHELPER_SERVICEDECL_getFactory
     347             : 
     348             : } // namespace service_decl
     349             : } // namespace comphelper
     350             : 
     351             : /** The following preprocessor macro generates the C access functions,
     352             :     that are used to initialize and register the components of a
     353             :     shared library object.
     354             : 
     355             :     If you have, say, written a lib that contains three distinct
     356             :     components, each with its own ServiceDecl object, you might want
     357             :     to employ the following code:
     358             : 
     359             :     <pre>
     360             :         // must reside outside _any_ namespace
     361             :         COMPHELPER_SERVICEDECL_EXPORTS3(yourServiceDecl1,
     362             :                                        yourServiceDecl2,
     363             :                                        yourServiceDecl3);
     364             :     </pre>
     365             : 
     366             :     For your convenience, the COMPHELPER_SERVICEDECL_EXPORTS<N> macro
     367             :     comes pre-defined up to N=8, if you should need more arguments,
     368             :     call COMPHELPER_SERVICEDECL_make_exports directly, like this:
     369             : 
     370             :     <pre>
     371             :         // must reside outside _any_ namespace
     372             :         COMPHELPER_SERVICEDECL_make_exports((yourServiceDecl1)(yourServiceDecl2)...(yourServiceDeclN));
     373             :     </pre>
     374             : 
     375             :     Note the missing colons between the bracketed arguments.
     376             :  */
     377             : #define COMPHELPER_SERVICEDECL_make_exports(compName, varargs_ ) \
     378             : extern "C" \
     379             : { \
     380             :     SAL_DLLPUBLIC_EXPORT void* SAL_CALL compName##_component_getFactory( sal_Char const* pImplName, \
     381             :                                          void*   pServiceManager, \
     382             :                                          void*       pRegistryKey ) \
     383             :     { \
     384             :         return component_getFactoryHelper( pImplName, static_cast<css::lang::XMultiServiceFactory *>(pServiceManager), \
     385             :                                            static_cast<css::registry::XRegistryKey *>(pRegistryKey), \
     386             :                                            BOOST_PP_SEQ_ENUM(varargs_) ); \
     387             :     } \
     388             : }
     389             : 
     390             : #define COMPHELPER_SERVICEDECL_EXPORTS1(compName,comp0_)    \
     391             :     COMPHELPER_SERVICEDECL_make_exports(compName,(comp0_))
     392             : #define COMPHELPER_SERVICEDECL_EXPORTS2(compName,comp0_,comp1_) \
     393             :     COMPHELPER_SERVICEDECL_make_exports(compName,(comp0_)(comp1_))
     394             : #define COMPHELPER_SERVICEDECL_EXPORTS3(compName,comp0_,comp1_,comp2_) \
     395             :     COMPHELPER_SERVICEDECL_make_exports(compName,(comp0_)(comp1_)(comp2_))
     396             : #define COMPHELPER_SERVICEDECL_EXPORTS4(compName,comp0_,comp1_,comp2_,comp3_) \
     397             :     COMPHELPER_SERVICEDECL_make_exports(compName,(comp0_)(comp1_)(comp2_)(comp3_))
     398             : #define COMPHELPER_SERVICEDECL_EXPORTS5(compName,comp0_,comp1_,comp2_,comp3_,comp4_) \
     399             :     COMPHELPER_SERVICEDECL_make_exports(compName,(comp0_)(comp1_)(comp2_)(comp3_)(comp4_))
     400             : #define COMPHELPER_SERVICEDECL_EXPORTS6(compName,comp0_,comp1_,comp2_,comp3_,comp4_,comp5_) \
     401             :     COMPHELPER_SERVICEDECL_make_exports(compName,(comp0_)(comp1_)(comp2_)(comp3_)(comp4_)(comp5_))
     402             : #define COMPHELPER_SERVICEDECL_EXPORTS7(compName,comp0_,comp1_,comp2_,comp3_,comp4_,comp5_,comp6_) \
     403             :     COMPHELPER_SERVICEDECL_make_exports(compName,(comp0_)(comp1_)(comp2_)(comp3_)(comp4_)(comp5_)(comp6_))
     404             : #define COMPHELPER_SERVICEDECL_EXPORTS8(compName,comp0_,comp1_,comp2_,comp3_,comp4_,comp5_,comp6_,comp7_) \
     405             :     COMPHELPER_SERVICEDECL_make_exports(compName,(comp0_)(comp1_)(comp2_)(comp3_)(comp4_)(comp5_)(comp6_)(comp7_))
     406             : 
     407             : #endif //  ! defined( INCLUDED_COMPHELPER_SERVICEDECL_HXX)
     408             : 
     409             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10