initial load of upstream version 1.06.32
[xmlrpc-c] / include / xmlrpc-c / oldcppwrapper.hpp
1 // -*- C++ -*-   <-- an Emacs control
2
3 // Copyright information is at the bottom of the file.
4
5 //=========================================================================
6 //  XML-RPC C++ API
7 //=========================================================================
8
9
10 #ifndef XMLRPCCPP_H_INCLUDED
11 #define XMLRPCCPP_H_INCLUDED
12
13 // There used to be a "using namespace std" here and some confusing old
14 // comments about it having something to do with what header file you
15 // include to get string functions.
16 //
17 // "using namespace std" was under "#if defined(__GNUC__) && (__GNUC__ >= 3)"
18 // until December 2003, and then unconditional until Release 1.1 (March 2005).
19 // Older GNU Compilers apparently imply namespace std, so they don't need it.
20 // 
21 // But "using namespace std" is a bad idea.  This is an interface header
22 // file, and we don't want to suck all of namespace std into the user's
23 // namespace just because he's using Xmlrpc-c.  So we took it out.
24 // We refer to std names like std::string.
25 // -Bryan 2005.03.12.
26
27
28 #include <cstdlib>
29 #include <string>
30 #include <xmlrpc-c/base.h>
31 #include <xmlrpc-c/client.h>
32 #include <xmlrpc-c/server.h>
33
34
35 //=========================================================================
36 //  XmlRpcFault
37 //=========================================================================
38 //  A C++ exception class representing an XML-RPC fault.
39
40 class XmlRpcFault {
41
42 private:
43     xmlrpc_env   mFault;
44
45     XmlRpcFault& operator= (XmlRpcFault const& f)
46         { if (true || f.getFaultCode()) abort(); return (XmlRpcFault&) f; }
47
48 public:
49     XmlRpcFault (const XmlRpcFault &fault);
50     XmlRpcFault (const int faultCode, const std::string faultString);
51     XmlRpcFault (const xmlrpc_env *env);
52     ~XmlRpcFault (void);
53
54     int          getFaultCode (void) const;
55     std::string  getFaultString (void) const;
56     xmlrpc_env  *getFaultEnv (void);
57 };
58
59 inline int XmlRpcFault::getFaultCode (void) const {
60     return mFault.fault_code;
61 }
62
63 inline xmlrpc_env *XmlRpcFault::getFaultEnv (void) {
64     return &mFault;
65 }
66
67
68 //=========================================================================
69 //  XmlRpcEnv
70 //=========================================================================
71 //  This class can be used to wrap xmlrpc_env object. Use it as follows:
72 //
73 //    XmlRpcEnv env;
74 //    xmlrpc_parse_value(env, v, "(i)", &i);
75 //    env.throwIfFaultOccurred();        
76
77 class XmlRpcEnv {
78
79 private:
80     xmlrpc_env   mEnv;
81
82     void         throwMe (void) const;
83     XmlRpcEnv&   operator= (XmlRpcEnv const& e)
84         { if (true || e.faultOccurred()) abort(); return (XmlRpcEnv&) e;}
85
86 public:
87     XmlRpcEnv (const XmlRpcEnv &env);
88     XmlRpcEnv (void) { xmlrpc_env_init(&mEnv); }
89     ~XmlRpcEnv (void) { xmlrpc_env_clean(&mEnv); }
90     
91     bool         faultOccurred (void) const { return mEnv.fault_occurred; };
92     bool         hasFaultOccurred (void) const { return faultOccurred(); };
93         /* hasFaultOccurred() is for backward compatibility.
94            faultOccurred() is a superior name for this.
95         */
96     std::string  getFaultString() const { return mEnv.fault_string; };
97     XmlRpcFault  getFault (void) const;
98
99     void         throwIfFaultOccurred (void) const;
100
101     operator xmlrpc_env * (void) { return &mEnv; }
102 };
103
104 inline void XmlRpcEnv::throwIfFaultOccurred (void) const {
105     if (faultOccurred())
106         throwMe();
107 }
108
109
110 //=========================================================================
111 //  XmlRpcValue
112 //=========================================================================
113 //  An object in this class is an XML-RPC value.
114 //
115 //  We have a complex structure to allow C code mixed in with C++ code
116 //  which uses this class to refer to the same XML-RPC value object.
117 //  This is especially important because there aren't proper C++ facilities
118 //  for much of Xmlrpc-c; you have to use the C facilities even if you'd
119 //  rather use proper C++.
120 //
121 //  The XmlRpcValue object internally represents the value as an
122 //  xmlrpc_value.  It holds one reference to the xmlrpc_value.  Users
123 //  of XmlRpcValue never see that xmlrpc_value, but C code can.  the
124 //  C code might create the xmlrpc_value and then bind it to an XmlRpcValue,
125 //  or it might get the xmlrpc_value handle from the XmlRpcValue.  Finally,
126 //  C code can simply use the XmlRpcValue where an xmlrpc_value handle is
127 //  required and it gets converted automatically.
128 //
129 //  So reference counting for the xmlrpc_value is quite a nightmare.
130
131 class XmlRpcValue {
132
133 private:
134     xmlrpc_value *mValue;
135
136 public:
137     enum ReferenceBehavior {
138         MAKE_REFERENCE,
139         CONSUME_REFERENCE
140     };
141
142     typedef xmlrpc_int32 int32;
143     
144     XmlRpcValue (void);
145     XmlRpcValue (xmlrpc_value *value,
146                  ReferenceBehavior behavior = MAKE_REFERENCE);
147     XmlRpcValue (const XmlRpcValue& value);
148     ~XmlRpcValue (void);
149     
150     XmlRpcValue&  operator= (const XmlRpcValue& value);
151
152     // Accessing the value's type (think of this as lightweight RTTI).
153     xmlrpc_type getType(void) const;
154     
155     // We don't supply an automatic conversion operator--you need to say
156     // whether you want to make or borrow this object's reference.
157     // XXX - Is it really OK for these to be const?
158     xmlrpc_value *makeReference (void) const;
159     xmlrpc_value *borrowReference (void) const;
160
161     // Some static "constructor" functions.
162     static XmlRpcValue makeInt      (const XmlRpcValue::int32 i);
163     static XmlRpcValue makeBool     (const bool b);
164     static XmlRpcValue makeDouble   (const double d);
165     static XmlRpcValue makeDateTime (const std::string& dateTime);
166     static XmlRpcValue makeString   (const std::string& str);
167     static XmlRpcValue makeString   (const char *const str);
168     static XmlRpcValue makeString   (const char *const str, size_t len);
169     static XmlRpcValue makeArray    (void);
170     static XmlRpcValue makeStruct   (void);
171     static XmlRpcValue makeBase64   (const unsigned char *const data,
172                                      size_t len);
173     /*
174     // An interface to xmlrpc_build_value.
175     static XmlRpcValue buildValue (const char *const format, ...);
176     */
177
178     // Some functions to get the underlying data.
179     // These will throw an XmlRpcFault if the data is the wrong type.
180     XmlRpcValue::int32 getInt   (void) const;
181     bool         getBool        (void) const;
182     double       getDouble      (void) const;
183     std::string  getRawDateTime (void) const;
184     std::string  getString      (void) const;
185     XmlRpcValue  getArray       (void) const;
186     XmlRpcValue  getStruct      (void) const;
187
188     // This returns an internal pointer which will become invalid when
189     // all references to the underlying value are destroyed.
190     void         getBase64      (const unsigned char *& out_data,
191                                  size_t& out_len) const;
192
193     /*
194     // An interface to xmlrpc_parse_value.
195     void parseValue (const char *const format, ...);
196     */
197
198     // Array functions. These will throw an XmlRpcFault if the value
199     // isn't an array.
200     size_t       arraySize (void) const;
201     void         arrayAppendItem (const XmlRpcValue& value);
202     XmlRpcValue  arrayGetItem (int index) const;
203     
204     // Struct functions. These will throw an XmlRpcFault if the value
205     // isn't a struct.
206     size_t       structSize (void) const;
207     bool         structHasKey (const std::string& key) const;
208     XmlRpcValue  structGetValue (const std::string& key) const;
209     void         structSetValue (const std::string& key, 
210                                  const XmlRpcValue& value);
211     void         structGetKeyAndValue (const int index,
212                                        std::string& out_key,
213                                        XmlRpcValue& out_value) const;
214 };
215
216 inline XmlRpcValue::XmlRpcValue (xmlrpc_value *value,
217                                  ReferenceBehavior behavior) 
218 {
219     mValue = value;
220
221     if (behavior == MAKE_REFERENCE)
222         xmlrpc_INCREF(value);
223 }
224
225 inline XmlRpcValue::XmlRpcValue (const XmlRpcValue& value) {
226     mValue = value.mValue;
227     xmlrpc_INCREF(mValue);
228 }
229
230 inline XmlRpcValue::~XmlRpcValue (void) {
231     xmlrpc_DECREF(mValue);
232 }
233
234 inline XmlRpcValue& XmlRpcValue::operator= (const XmlRpcValue& value) {
235     // Must increment before we decrement, in case of assignment to self.
236     xmlrpc_INCREF(value.mValue);
237     xmlrpc_DECREF(mValue);
238     mValue = value.mValue;
239     return *this;
240 }
241
242 inline xmlrpc_type XmlRpcValue::getType (void) const {
243     return xmlrpc_value_type(mValue);
244 }
245
246 inline xmlrpc_value *XmlRpcValue::makeReference (void) const {
247     xmlrpc_INCREF(mValue);
248     return mValue;
249 }
250
251 inline xmlrpc_value *XmlRpcValue::borrowReference (void) const {
252     return mValue;
253 }
254
255
256 //=========================================================================
257 //  XmlRpcClient
258 //=========================================================================
259
260 class XmlRpcClient {
261
262 private:
263     std::string mServerUrl;
264
265 public:
266     static void Initialize (std::string appname, std::string appversion);
267     static void Terminate (void);
268
269     XmlRpcClient (const std::string& server_url) : mServerUrl(server_url) {}
270     ~XmlRpcClient (void) {}
271
272     XmlRpcClient (const XmlRpcClient& client);
273     XmlRpcClient& operator= (const XmlRpcClient& client);
274
275     XmlRpcValue call (std::string method_name, XmlRpcValue param_array);
276     void call_asynch (std::string method_name,
277                       XmlRpcValue param_array,
278                       xmlrpc_response_handler callback,
279                       void* user_data);
280     void event_loop_asynch (unsigned long milliseconds);
281 };
282
283 inline void XmlRpcClient::call_asynch(std::string method_name,
284                                       XmlRpcValue param_array,
285                                       xmlrpc_response_handler callback,
286                                       void* user_data)
287 {
288     xmlrpc_client_call_asynch_params(
289         mServerUrl.c_str(),
290         method_name.c_str(),
291         callback,
292         user_data,
293         param_array.borrowReference());
294 }
295
296 inline void XmlRpcClient::event_loop_asynch(unsigned long milliseconds)
297 {
298     xmlrpc_client_event_loop_finish_asynch_timeout(milliseconds);
299 }
300
301
302 //=========================================================================
303 //  XmlRpcClient Methods
304 //=========================================================================
305 //  These are inline for now, so we don't need to screw with linker issues
306 //  and build a separate client library.
307
308 inline XmlRpcClient::XmlRpcClient (const XmlRpcClient& client)
309     : mServerUrl(client.mServerUrl)
310 {
311 }
312
313 inline XmlRpcClient& XmlRpcClient::operator= (const XmlRpcClient& client) {
314     if (this != &client)
315         mServerUrl = client.mServerUrl;
316     return *this;
317 }
318
319 inline void XmlRpcClient::Initialize (std::string appname, 
320                                       std::string appversion) {
321     xmlrpc_client_init(XMLRPC_CLIENT_NO_FLAGS,
322                        appname.c_str(),
323                        appversion.c_str());
324 }
325
326 inline void XmlRpcClient::Terminate (void) {
327     xmlrpc_client_cleanup();
328 }
329
330 inline XmlRpcValue XmlRpcClient::call (std::string method_name,
331                                        XmlRpcValue param_array)
332 {
333     XmlRpcEnv env;
334     xmlrpc_value *result =
335     xmlrpc_client_call_params(env,
336                               mServerUrl.c_str(),
337                               method_name.c_str(),
338                               param_array.borrowReference());
339     env.throwIfFaultOccurred();
340     return XmlRpcValue(result, XmlRpcValue::CONSUME_REFERENCE);
341 }
342
343 //=========================================================================
344 //  XmlRpcGenSrv
345 //=========================================================================
346
347 class XmlRpcGenSrv {
348
349 private:
350
351     xmlrpc_registry*    mRegistry;
352
353     xmlrpc_mem_block* alloc (XmlRpcEnv& env, const std::string& body) const; 
354
355 public:
356
357     XmlRpcGenSrv (int flags);
358     ~XmlRpcGenSrv (void);
359
360     xmlrpc_registry* getRegistry (void) const;
361
362     XmlRpcGenSrv&   addMethod (const std::string& name,
363                                xmlrpc_method method,
364                                void *data);
365     XmlRpcGenSrv&   addMethod (const std::string& name,
366                                xmlrpc_method method,
367                                void* data,
368                                const std::string& signature,
369                                const std::string& help);
370     
371     std::string handle (const std::string& body) const;
372 };
373
374 inline XmlRpcGenSrv::XmlRpcGenSrv (int) {
375
376     XmlRpcEnv env;
377
378     mRegistry = xmlrpc_registry_new (env);
379     env.throwIfFaultOccurred();        
380 }
381
382 inline XmlRpcGenSrv::~XmlRpcGenSrv (void) {
383
384     xmlrpc_registry_free (mRegistry);
385 }
386
387 inline xmlrpc_registry* XmlRpcGenSrv::getRegistry () const {
388
389     return mRegistry;
390 }
391
392
393 // Copyright (C) 2001 by Eric Kidd. All rights reserved.
394 //
395 // Redistribution and use in source and binary forms, with or without
396 // modification, are permitted provided that the following conditions
397 // are met:
398 // 1. Redistributions of source code must retain the above copyright
399 //    notice, this list of conditions and the following disclaimer.
400 // 2. Redistributions in binary form must reproduce the above copyright
401 //    notice, this list of conditions and the following disclaimer in the
402 //    documentation and/or other materials provided with the distribution.
403 // 3. The name of the author may not be used to endorse or promote products
404 //    derived from this software without specific prior written permission. 
405 //  
406 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
407 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
408 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
409 // ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
410 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
411 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
412 // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
413 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
414 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
415 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
416 // SUCH DAMAGE.
417
418
419 #endif /* _XMLRPCCPP_H_ */