1 /***************************************************************************
2 ulxr-method_adder.h - interface for adding methods
3 -------------------
4 begin : Thu Jul 12 2007
5 copyright : (C) 2002-2007 by Ewald Arnold
6 email : ulxmlrpcpp@ewald-arnold.de
7
8 $Id: ulxr_method_adder.h 1164 2010-01-06 10:03:51Z ewald-arnold $
9
10 ***************************************************************************/
11
12 /**************************************************************************
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License as
16 * published by the Free Software Foundation; either version 2 of the License,
17 * or (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU Lesser General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 *
28 ***************************************************************************/
29
30 #ifndef ULXR_METHOD_ADDER_H
31 #define ULXR_METHOD_ADDER_H
32
33 #include <ulxmlrpcpp/ulxmlrpcpp.h> // always first header
34
35 namespace ulxr {
36
37
38 class MethodResponse;
39 class MethodCall;
40 class Dispatcher;
41 class Signature;
42
43
44 namespace hidden {
45
46
47 /** Internal helper class, not intended for public use.
48 */
49 class ULXR_API_DECL0 MethodWrapperBase
50 {
51 public:
52
53 virtual ~MethodWrapperBase();
54
55 virtual MethodResponse call(const MethodCall &calldata) const = 0;
56 };
57
58
59 /** Internal helper class template, not intended for public use.
60 */
61 template <class T>
62 class MethodWrapper : public MethodWrapperBase
63 {
64 public:
65
66 typedef MethodResponse (T::*PMF)(const MethodCall &calldata);
67
~MethodWrapper()68 virtual ~MethodWrapper()
69 {
70 }
71
call(const MethodCall & calldata)72 virtual MethodResponse call (const MethodCall &calldata) const
73 {
74 return (obj->*adr) (calldata);
75 }
76
MethodWrapper(T * o,PMF a)77 MethodWrapper(T *o, PMF a)
78 : obj(o), adr(a)
79 {}
80
81 private:
82 T *obj;
83 PMF adr ;
84
85 private:
86 // forbid them all due to internal pointers
87 const MethodWrapper& operator= (const MethodWrapper&);
88 MethodWrapper (const MethodWrapper&);
89 };
90
91
92 } // namespace hidden
93
94
95 /** Define interface for adding rpc method to a dispatcher
96 * @ingroup grp_ulxr_rpc
97 */
98 class ULXR_API_DECL0 MethodAdder
99 {
100 public:
101
102 typedef MethodResponse (*StaticMethodCall_t)(const MethodCall &);
103
104 typedef MethodResponse (*SystemMethodCall_t)(const MethodCall &,
105 const Dispatcher* disp);
106
107 typedef hidden::MethodWrapperBase* DynamicMethodCall_t; // call Wrappers call();
108
109 enum CallType { CallNone,
110 CallSystem,
111 CallStatic,
112 CallDynamic
113 };
114
115 protected:
116
117 friend StaticMethodCall_t make_method(const StaticMethodCall_t);
118
119 typedef union
120 {
121 StaticMethodCall_t static_function;
122 SystemMethodCall_t system_function;
123 DynamicMethodCall_t dynamic_function;
124 } MethodCall_t;
125
126 public:
127
~MethodAdder()128 virtual ~MethodAdder()
129 {}
130
131 /** Adds a user defined (static) method to the dispatcher.
132 * You access a remote method by sending the "official" name. Sometimes
133 * a method accepts different parameter sets (overloading in C++).
134 * In this case you add the according signature. Finally you can
135 * add a description to show the usage of this method.
136 * @param adr the pointer to the implementation of the method
137 * @param ret_signature the signature of the return value
138 * @param name the name of the method
139 * @param signature the signature of the parameters
140 * @param help short usage description
141 */
142 virtual void addMethod (StaticMethodCall_t adr,
143 const CppString &ret_signature,
144 const CppString &name,
145 const CppString &signature,
146 const CppString &help) = 0;
147
148 /** Adds a user defined (dynamic) method to the dispatcher.
149 * You access a remote method by sending the "official" name. Sometimes
150 * a method accepts different parameter sets (overloading in C++).
151 * In this case you add the according signature. Finally you can
152 * add a description to show the usage of this method.
153 * @param wrapper the pointer to the wrapper to the method.
154 * Important: Dispatcher owns now and deletes this wrapper object!
155 * @param ret_signature the signature of the return value
156 * @param name the name of the method
157 * @param signature the signature of the parameters
158 * @param help short usage description
159 */
160 virtual void addMethod (DynamicMethodCall_t wrapper,
161 const CppString &ret_signature,
162 const CppString &name,
163 const CppString &signature,
164 const CppString &help) = 0;
165
166 /** Adds a system internal method to the dispatcher.
167 * You access a remote method by sending the "official" name. Sometimes
168 * a method accepts different parameter sets (overloading in C++).
169 * In this case you add the according signature. Finally you can
170 * add a description to show the usage of this method.
171 * @param adr the pointer to the implementation of the method
172 * @param ret_signature the signature of the return value
173 * @param name the name of the method
174 * @param signature the signature of the parameters
175 * @param help short usage description
176 */
177 virtual void addMethod (SystemMethodCall_t adr,
178 const CppString &ret_signature,
179 const CppString &name,
180 const CppString &signature,
181 const CppString &help) = 0;
182
183 /** Adds a user defined (static) method to the dispatcher.
184 * You access a remote method by sending the "official" name. Sometimes
185 * a method accepts different parameter sets (overloading in C++).
186 * In this case you add the according signature. Finally you can
187 * add a description to show the usage of this method.
188 * @param adr the pointer to the implementation of the method
189 * @param ret_signature the signature of the return value
190 * @param name the name of the method
191 * @param signature the signature of the parameters
192 * @param help short usage description
193 */
194 virtual void addMethod (StaticMethodCall_t adr,
195 const Signature &ret_signature,
196 const CppString &name,
197 const Signature &signature,
198 const CppString &help) = 0;
199
200 /** Adds a user defined (dynamic) method to the dispatcher.
201 * You access a remote method by sending the "official" name. Sometimes
202 * a method accepts different parameter sets (overloading in C++).
203 * In this case you add the according signature. Finally you can
204 * add a description to show the usage of this method.
205 * @param wrapper the pointer to the wrapper to the method.
206 * Important: Dispatcher owns now and deletes this wrapper object!
207 * @param ret_signature the signature of the return value
208 * @param name the name of the method
209 * @param signature the signature of the parameters
210 * @param help short usage description
211 */
212 virtual void addMethod (DynamicMethodCall_t wrapper,
213 const Signature &ret_signature,
214 const CppString &name,
215 const Signature &signature,
216 const CppString &help) = 0;
217
218 /** Adds a system internal method to the dispatcher.
219 * You access a remote method by sending the "official" name. Sometimes
220 * a method accepts different parameter sets (overloading in C++).
221 * In this case you add the according signature. Finally you can
222 * add a description to show the usage of this method.
223 * @param adr the pointer to the implementation of the method
224 * @param ret_signature the signature of the return value
225 * @param name the name of the method
226 * @param signature the signature of the parameters
227 * @param help short usage description
228 */
229 virtual void addMethod (SystemMethodCall_t adr,
230 const Signature &ret_signature,
231 const CppString &name,
232 const Signature &signature,
233 const CppString &help) = 0;
234
235 /** Removes a method if available
236 * @param name method name
237 */
238 virtual void removeMethod(const CppString &name) = 0;
239 };
240
241
242 /** Creates a wrapper object to a method of a worker class.
243 * new ulxr::hidden::MethodWrapper<classname> (&obj, &classname::method),
244 * @param w reference to worker class
245 * @param pmf adress of member function in worker class
246 * @return pointer to wrapper object
247 */
248
249 #ifndef _MSC_VER
250
251 template <class T>
252 inline hidden::MethodWrapperBase*
make_method(T & w,typename hidden::MethodWrapper<T>::PMF pmf)253 make_method(T &w, typename hidden::MethodWrapper<T>::PMF pmf)
254 {
255 return new hidden::MethodWrapper<T> (&w, pmf);
256 }
257
258 #else // work around m$vc bug
259
260 template <class T, class U>
261 inline hidden::MethodWrapper<T>*
make_method(T & w,U pmf)262 make_method(T &w, U pmf)
263 {
264 return new hidden::MethodWrapper<T> (&w, pmf);
265 }
266
267 #endif
268
269 typedef MethodAdder::StaticMethodCall_t MethodAdder_StaticMethodCall_t;
270
271 /** Specialisation of template to achive uniform look in responder creation.
272 * @param ptr pointer to worker function
273 * @return pointer to the function
274 */
275 inline MethodAdder_StaticMethodCall_t
make_method(MethodAdder_StaticMethodCall_t ptr)276 make_method(MethodAdder_StaticMethodCall_t ptr)
277 {
278 return ptr;
279 }
280
281
282 } // namespace
283
284 #endif // ULXR_METHOD_ADDER_H
285