1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #if ! defined(COMPHELPER_UNWRAPARGS_HXX_INCLUDED)
29 #define COMPHELPER_UNWRAPARGS_HXX_INCLUDED
30 
31 #if ! defined(_RTL_USTRBUF_HXX_)
32 #include "rtl/ustrbuf.hxx"
33 #endif
34 #include "com/sun/star/uno/Sequence.hxx"
35 #if ! defined(_COM_SUN_STAR_LANG_ILLEGALARGUMENTEXCEPTION_HPP_)
36 #include "com/sun/star/lang/IllegalArgumentException.hpp"
37 #endif
38 #include "boost/optional.hpp"
39 #include "boost/preprocessor/cat.hpp"
40 #include "boost/preprocessor/repetition.hpp"
41 #include "boost/preprocessor/arithmetic/add.hpp"
42 #include "cppu/unotype.hxx"
43 
44 namespace comphelper {
45 
46 //
47 // generating helper functions to unwrap the service's argument sequence:
48 //
49 
50 /// @internal
51 namespace detail {
52 
53 template <typename T>
54 inline void extract(
55     ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any> const& seq,
56     sal_Int32 nArg, T & v,
57     ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface>
58     const& xErrorContext )
59 {
60     if (nArg >= seq.getLength()) {
61         throw ::com::sun::star::lang::IllegalArgumentException(
62             ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
63                                  "No such argument available!") ),
64             xErrorContext, static_cast<sal_Int16>(nArg) );
65     }
66     if (! (seq[nArg] >>= v)) {
67         ::rtl::OUStringBuffer buf;
68         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("Cannot extract ANY { ") );
69         buf.append( seq[nArg].getValueType().getTypeName() );
70         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" } to ") );
71         buf.append( ::cppu::UnoType<T>::get().getTypeName() );
72         buf.append( static_cast<sal_Unicode>('!') );
73         throw ::com::sun::star::lang::IllegalArgumentException(
74             buf.makeStringAndClear(), xErrorContext,
75             static_cast<sal_Int16>(nArg) );
76     }
77 }
78 
79 template <typename T>
80 inline void extract(
81     ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any> const& seq,
82     sal_Int32 nArg, ::boost::optional<T> & v,
83     ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface>
84     const& xErrorContext )
85 {
86     if (nArg < seq.getLength()) {
87         T t;
88         extract( seq, nArg, t, xErrorContext );
89         v.reset( t );
90     }
91 }
92 
93 } // namespace detail
94 
95 #define COMPHELPER_UNWRAPARGS_extract(z_, n_, unused_) \
96     detail::extract( seq, n_, BOOST_PP_CAT(v, n_), xErrorContext );
97 #define COMPHELPER_UNWRAPARGS_args(z_, n_, unused_) \
98     BOOST_PP_CAT(T, n_) & BOOST_PP_CAT(v, n_)
99 
100 /** The following preprocessor repetitions generate functions like
101 
102     <pre>
103         template <typename T0, typename T1, ...>
104         inline void unwrapArgs(
105             uno::Sequence<uno::Any> const& seq,
106             T0 & v0, T1 & v1, ...,
107             css::uno::Reference<css::uno::XInterface> const& xErrorContext =
108             css::uno::Reference<css::uno::XInterface>() );
109     </pre>
110     (full namespace qualification ::com::sun::star has been omitted
111     for brevity)
112 
113     which unwraps the passed sequence's elements, assigning them to the
114     referenced values.  Specify optional arguments as boost::optional<T>.
115     If the length of the sequence is greater than the count of arguments,
116     then the latter sequence elements are ignored.
117     If too few arguments are given in the sequence and a missing argument is
118     no boost::optional<T>, then an lang::IllegalArgumentException is thrown
119     with the specified xErrorContext (defaults to null-ref).
120 
121     The maximum number of service declarations can be set by defining
122     COMPHELPER_UNWRAPARGS_MAX_ARGS; its default is 12.
123 */
124 #define COMPHELPER_UNWRAPARGS_make(z_, n_, unused_) \
125 template < BOOST_PP_ENUM_PARAMS( BOOST_PP_ADD(n_, 1), typename T) > \
126 inline void unwrapArgs( \
127     ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > const& seq, \
128     BOOST_PP_ENUM(BOOST_PP_ADD(n_, 1), COMPHELPER_UNWRAPARGS_args, ~), \
129     ::com::sun::star::uno::Reference< \
130     ::com::sun::star::uno::XInterface> const& xErrorContext = \
131     ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface>() ) \
132 { \
133     BOOST_PP_REPEAT(BOOST_PP_ADD(n_, 1), COMPHELPER_UNWRAPARGS_extract, ~) \
134 }
135 
136 #if ! defined(COMPHELPER_UNWRAPARGS_MAX_ARGS)
137 #define COMPHELPER_UNWRAPARGS_MAX_ARGS 12
138 #endif
139 
140 BOOST_PP_REPEAT(COMPHELPER_UNWRAPARGS_MAX_ARGS, COMPHELPER_UNWRAPARGS_make, ~)
141 
142 #undef COMPHELPER_UNWRAPARGS_MAX_ARGS
143 #undef COMPHELPER_UNWRAPARGS_make
144 #undef COMPHELPER_UNWRAPARGS_args
145 #undef COMPHELPER_UNWRAPARGS_extract
146 
147 } // namespace comphelper
148 
149 #endif //  ! defined(COMPHELPER_UNWRAPARGS_HXX_INCLUDED)
150 
151