1 // -*- C++ -*- <-- an Emacs control
3 // Copyright information is at the bottom of the file.
5 //=========================================================================
7 //=========================================================================
10 #ifndef XMLRPCCPP_H_INCLUDED
11 #define XMLRPCCPP_H_INCLUDED
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.
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.
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.
30 #include <xmlrpc-c/base.h>
31 #include <xmlrpc-c/client.h>
32 #include <xmlrpc-c/server.h>
35 //=========================================================================
37 //=========================================================================
38 // A C++ exception class representing an XML-RPC fault.
45 XmlRpcFault& operator= (XmlRpcFault const& f)
46 { if (true || f.getFaultCode()) abort(); return (XmlRpcFault&) f; }
49 XmlRpcFault (const XmlRpcFault &fault);
50 XmlRpcFault (const int faultCode, const std::string faultString);
51 XmlRpcFault (const xmlrpc_env *env);
54 int getFaultCode (void) const;
55 std::string getFaultString (void) const;
56 xmlrpc_env *getFaultEnv (void);
59 inline int XmlRpcFault::getFaultCode (void) const {
60 return mFault.fault_code;
63 inline xmlrpc_env *XmlRpcFault::getFaultEnv (void) {
68 //=========================================================================
70 //=========================================================================
71 // This class can be used to wrap xmlrpc_env object. Use it as follows:
74 // xmlrpc_parse_value(env, v, "(i)", &i);
75 // env.throwIfFaultOccurred();
82 void throwMe (void) const;
83 XmlRpcEnv& operator= (XmlRpcEnv const& e)
84 { if (true || e.faultOccurred()) abort(); return (XmlRpcEnv&) e;}
87 XmlRpcEnv (const XmlRpcEnv &env);
88 XmlRpcEnv (void) { xmlrpc_env_init(&mEnv); }
89 ~XmlRpcEnv (void) { xmlrpc_env_clean(&mEnv); }
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.
96 std::string getFaultString() const { return mEnv.fault_string; };
97 XmlRpcFault getFault (void) const;
99 void throwIfFaultOccurred (void) const;
101 operator xmlrpc_env * (void) { return &mEnv; }
104 inline void XmlRpcEnv::throwIfFaultOccurred (void) const {
110 //=========================================================================
112 //=========================================================================
113 // An object in this class is an XML-RPC value.
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++.
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.
129 // So reference counting for the xmlrpc_value is quite a nightmare.
134 xmlrpc_value *mValue;
137 enum ReferenceBehavior {
142 typedef xmlrpc_int32 int32;
145 XmlRpcValue (xmlrpc_value *value,
146 ReferenceBehavior behavior = MAKE_REFERENCE);
147 XmlRpcValue (const XmlRpcValue& value);
150 XmlRpcValue& operator= (const XmlRpcValue& value);
152 // Accessing the value's type (think of this as lightweight RTTI).
153 xmlrpc_type getType(void) const;
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;
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,
174 // An interface to xmlrpc_build_value.
175 static XmlRpcValue buildValue (const char *const format, ...);
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;
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;
194 // An interface to xmlrpc_parse_value.
195 void parseValue (const char *const format, ...);
198 // Array functions. These will throw an XmlRpcFault if the value
200 size_t arraySize (void) const;
201 void arrayAppendItem (const XmlRpcValue& value);
202 XmlRpcValue arrayGetItem (int index) const;
204 // Struct functions. These will throw an XmlRpcFault if the value
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;
216 inline XmlRpcValue::XmlRpcValue (xmlrpc_value *value,
217 ReferenceBehavior behavior)
221 if (behavior == MAKE_REFERENCE)
222 xmlrpc_INCREF(value);
225 inline XmlRpcValue::XmlRpcValue (const XmlRpcValue& value) {
226 mValue = value.mValue;
227 xmlrpc_INCREF(mValue);
230 inline XmlRpcValue::~XmlRpcValue (void) {
231 xmlrpc_DECREF(mValue);
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;
242 inline xmlrpc_type XmlRpcValue::getType (void) const {
243 return xmlrpc_value_type(mValue);
246 inline xmlrpc_value *XmlRpcValue::makeReference (void) const {
247 xmlrpc_INCREF(mValue);
251 inline xmlrpc_value *XmlRpcValue::borrowReference (void) const {
256 //=========================================================================
258 //=========================================================================
263 std::string mServerUrl;
266 static void Initialize (std::string appname, std::string appversion);
267 static void Terminate (void);
269 XmlRpcClient (const std::string& server_url) : mServerUrl(server_url) {}
270 ~XmlRpcClient (void) {}
272 XmlRpcClient (const XmlRpcClient& client);
273 XmlRpcClient& operator= (const XmlRpcClient& client);
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,
280 void event_loop_asynch (unsigned long milliseconds);
283 inline void XmlRpcClient::call_asynch(std::string method_name,
284 XmlRpcValue param_array,
285 xmlrpc_response_handler callback,
288 xmlrpc_client_call_asynch_params(
293 param_array.borrowReference());
296 inline void XmlRpcClient::event_loop_asynch(unsigned long milliseconds)
298 xmlrpc_client_event_loop_finish_asynch_timeout(milliseconds);
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.
308 inline XmlRpcClient::XmlRpcClient (const XmlRpcClient& client)
309 : mServerUrl(client.mServerUrl)
313 inline XmlRpcClient& XmlRpcClient::operator= (const XmlRpcClient& client) {
315 mServerUrl = client.mServerUrl;
319 inline void XmlRpcClient::Initialize (std::string appname,
320 std::string appversion) {
321 xmlrpc_client_init(XMLRPC_CLIENT_NO_FLAGS,
326 inline void XmlRpcClient::Terminate (void) {
327 xmlrpc_client_cleanup();
330 inline XmlRpcValue XmlRpcClient::call (std::string method_name,
331 XmlRpcValue param_array)
334 xmlrpc_value *result =
335 xmlrpc_client_call_params(env,
338 param_array.borrowReference());
339 env.throwIfFaultOccurred();
340 return XmlRpcValue(result, XmlRpcValue::CONSUME_REFERENCE);
343 //=========================================================================
345 //=========================================================================
351 xmlrpc_registry* mRegistry;
353 xmlrpc_mem_block* alloc (XmlRpcEnv& env, const std::string& body) const;
357 XmlRpcGenSrv (int flags);
358 ~XmlRpcGenSrv (void);
360 xmlrpc_registry* getRegistry (void) const;
362 XmlRpcGenSrv& addMethod (const std::string& name,
363 xmlrpc_method method,
365 XmlRpcGenSrv& addMethod (const std::string& name,
366 xmlrpc_method method,
368 const std::string& signature,
369 const std::string& help);
371 std::string handle (const std::string& body) const;
374 inline XmlRpcGenSrv::XmlRpcGenSrv (int) {
378 mRegistry = xmlrpc_registry_new (env);
379 env.throwIfFaultOccurred();
382 inline XmlRpcGenSrv::~XmlRpcGenSrv (void) {
384 xmlrpc_registry_free (mRegistry);
387 inline xmlrpc_registry* XmlRpcGenSrv::getRegistry () const {
393 // Copyright (C) 2001 by Eric Kidd. All rights reserved.
395 // Redistribution and use in source and binary forms, with or without
396 // modification, are permitted provided that the following conditions
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.
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
419 #endif /* _XMLRPCCPP_H_ */