| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428 |
- // -*- C++ -*- <-- an Emacs control
- // Copyright information is at the bottom of the file.
- //=========================================================================
- // XML-RPC C++ API
- //=========================================================================
- #ifndef _XMLRPCCPP_H_
- #define _XMLRPCCPP_H_ 1
- // The C++ standard says we should either include <string.h> (which gets
- // us the wrong header), or say 'using namespace std;' (which doesn't
- // work with our version of g++). So this header name is technically wrong.
- // Tell me what your compiler does; I can provide some autoconf magic to the
- // Right Thing on most platforms.
- //
- // 2004.12.22 Bryan: This looks like a problem with whatever g++ he was
- // using, so if anything, the special case should be for that. In any case,
- // we've already added using namespace std to other files, without knowing
- // there was an issue, so I'm just going to do the "using namespace"
- // unconditionally and see who complains. If there are complaints, we can
- // improve the documentation here.
- //
- // Formerly, the "using namespace std" was under
- // "#if defined(__GNUC__) && (__GNUC__ >= 3)".
- #include <string>
- using namespace std;
- #include <xmlrpc_config.h>
- #include <xmlrpc.h>
- #include <xmlrpc_client.h>
- #include <xmlrpc_server.h>
- #define XMLRPC_NO_ASSIGNMENT \
- XMLRPC_FATAL_ERROR("Assignment operator not available"); return *this;
- //=========================================================================
- // XmlRpcFault
- //=========================================================================
- // A C++ exception class representing an XML-RPC fault.
- class XmlRpcFault {
- private:
- xmlrpc_env mFault;
- XmlRpcFault& operator= (const XmlRpcFault& f)
- { (void) f; XMLRPC_NO_ASSIGNMENT }
- public:
- XmlRpcFault (const XmlRpcFault &fault);
- XmlRpcFault (const int faultCode, const string faultString);
- XmlRpcFault (const xmlrpc_env *env);
- ~XmlRpcFault (void);
- int getFaultCode (void) const;
- string getFaultString (void) const;
- xmlrpc_env *getFaultEnv (void);
- };
- inline int XmlRpcFault::getFaultCode (void) const {
- return mFault.fault_code;
- }
- inline xmlrpc_env *XmlRpcFault::getFaultEnv (void) {
- return &mFault;
- }
- //=========================================================================
- // XmlRpcEnv
- //=========================================================================
- // This class can be used to wrap xmlrpc_env object. Use it as follows:
- //
- // XmlRpcEnv env;
- // xmlrpc_parse_value(env, v, "(i)", &i);
- // env.throwIfFaultOccurred();
- class XmlRpcEnv {
- private:
- xmlrpc_env mEnv;
- void throwMe (void) const;
- XmlRpcEnv& operator= (const XmlRpcEnv& e)
- { (void) e; XMLRPC_NO_ASSIGNMENT }
- public:
- XmlRpcEnv (const XmlRpcEnv &env);
- XmlRpcEnv (void) { xmlrpc_env_init(&mEnv); }
- ~XmlRpcEnv (void) { xmlrpc_env_clean(&mEnv); }
-
- bool faultOccurred (void) const { return mEnv.fault_occurred; };
- bool hasFaultOccurred (void) const { return faultOccurred(); };
- /* hasFaultOccurred() is for backward compatibility.
- faultOccurred() is a superior name for this.
- */
- XmlRpcFault getFault (void) const;
- void throwIfFaultOccurred (void) const;
- operator xmlrpc_env * (void) { return &mEnv; }
- };
- inline void XmlRpcEnv::throwIfFaultOccurred (void) const {
- if (faultOccurred())
- throwMe();
- }
- //=========================================================================
- // XmlRpcValue
- //=========================================================================
- // An object in this class is an XML-RPC value.
- //
- // We have a complex structure to allow C code mixed in with C++ code
- // which uses this class to refer to the same XML-RPC value object.
- // This is especially important because there aren't proper C++ facilities
- // for much of Xmlrpc-c; you have to use the C facilities even if you'd
- // rather use proper C++.
- //
- // The XmlRpcValue object internally represents the value as an
- // xmlrpc_value. It hold one reference to the xmlrpc_value. Users
- // of XmlRpcValue never see that xmlrpc_value, but C code can. the
- // C code might create the xmlrpc_value and then bind it to an XmlRpcValue,
- // or it might get the xmlrpc_value handle from the XmlRpcValue. Finally,
- // C code can simply use the XmlRpcValue where an xmlrpc_value handle is
- // required and it gets converted automatically.
- //
- // So reference counting for the xmlrpc_value is quite a nightmare.
- class XmlRpcValue {
- private:
- xmlrpc_value *mValue;
- public:
- enum ReferenceBehavior {
- MAKE_REFERENCE,
- CONSUME_REFERENCE
- };
- typedef xmlrpc_int32 int32;
-
- XmlRpcValue (void);
- XmlRpcValue (xmlrpc_value *value,
- ReferenceBehavior behavior = MAKE_REFERENCE);
- XmlRpcValue (const XmlRpcValue& value);
- ~XmlRpcValue (void);
-
- XmlRpcValue& operator= (const XmlRpcValue& value);
- // Accessing the value's type (think of this as lightweight RTTI).
- xmlrpc_type getType(void) const;
-
- // We don't supply an automatic conversion operator--you need to say
- // whether you want to make or borrow this object's reference.
- // XXX - Is it really OK for these to be const?
- xmlrpc_value *makeReference (void) const;
- xmlrpc_value *borrowReference (void) const;
- // Some static "constructor" functions.
- static XmlRpcValue makeInt (const XmlRpcValue::int32 i);
- static XmlRpcValue makeBool (const bool b);
- static XmlRpcValue makeDouble (const double d);
- static XmlRpcValue makeDateTime (const string& dateTime);
- static XmlRpcValue makeString (const string& str);
- static XmlRpcValue makeString (const char *const str);
- static XmlRpcValue makeString (const char *const str, size_t len);
- static XmlRpcValue makeArray (void);
- static XmlRpcValue makeStruct (void);
- static XmlRpcValue makeBase64 (const unsigned char *const data,
- size_t len);
- /*
- // An interface to xmlrpc_build_value.
- static XmlRpcValue buildValue (const char *const format, ...);
- */
- // Some functions to get the underlying data.
- // These will throw an XmlRpcFault if the data is the wrong type.
- XmlRpcValue::int32 getInt (void) const;
- bool getBool (void) const;
- double getDouble (void) const;
- string getRawDateTime (void) const;
- string getString (void) const;
- XmlRpcValue getArray (void) const;
- XmlRpcValue getStruct (void) const;
- // This returns an internal pointer which will become invalid when
- // all references to the underlying value are destroyed.
- void getBase64 (const unsigned char *& out_data,
- size_t& out_len) const;
- /*
- // An interface to xmlrpc_parse_value.
- void parseValue (const char *const format, ...);
- */
- // Array functions. These will throw an XmlRpcFault if the value
- // isn't an array.
- size_t arraySize (void) const;
- void arrayAppendItem (const XmlRpcValue& value);
- XmlRpcValue arrayGetItem (int index) const;
-
- // Struct functions. These will throw an XmlRpcFault if the value
- // isn't a struct.
- size_t structSize (void) const;
- bool structHasKey (const string& key) const;
- XmlRpcValue structGetValue (const string& key) const;
- void structSetValue (const string& key, const XmlRpcValue& value);
- void structGetKeyAndValue (const int index,
- string& out_key,
- XmlRpcValue& out_value) const;
- };
- inline XmlRpcValue::XmlRpcValue (xmlrpc_value *value,
- ReferenceBehavior behavior)
- {
- mValue = value;
- if (behavior == MAKE_REFERENCE)
- xmlrpc_INCREF(value);
- }
- inline XmlRpcValue::XmlRpcValue (const XmlRpcValue& value) {
- mValue = value.mValue;
- xmlrpc_INCREF(mValue);
- }
- inline XmlRpcValue::~XmlRpcValue (void) {
- xmlrpc_DECREF(mValue);
- }
- inline XmlRpcValue& XmlRpcValue::operator= (const XmlRpcValue& value) {
- // Must increment before we decrement, in case of assignment to self.
- xmlrpc_INCREF(value.mValue);
- xmlrpc_DECREF(mValue);
- mValue = value.mValue;
- return *this;
- }
- inline xmlrpc_type XmlRpcValue::getType (void) const {
- return xmlrpc_value_type(mValue);
- }
- inline xmlrpc_value *XmlRpcValue::makeReference (void) const {
- xmlrpc_INCREF(mValue);
- return mValue;
- }
- inline xmlrpc_value *XmlRpcValue::borrowReference (void) const {
- return mValue;
- }
- //=========================================================================
- // XmlRpcClient
- //=========================================================================
- class XmlRpcClient {
- private:
- string mServerUrl;
- public:
- static void Initialize (string appname, string appversion);
- static void Terminate (void);
- XmlRpcClient (const string& server_url) : mServerUrl(server_url) {}
- ~XmlRpcClient (void) {}
- XmlRpcClient (const XmlRpcClient& client);
- XmlRpcClient& operator= (const XmlRpcClient& client);
- XmlRpcValue call (string method_name, XmlRpcValue param_array);
- void call_asynch (string method_name,
- XmlRpcValue param_array,
- xmlrpc_response_handler callback,
- void* user_data);
- void event_loop_asynch (unsigned long milliseconds);
- };
- inline void XmlRpcClient::call_asynch(string method_name,
- XmlRpcValue param_array,
- xmlrpc_response_handler callback,
- void* user_data)
- {
- xmlrpc_client_call_asynch_params(
- mServerUrl.c_str(),
- method_name.c_str(),
- callback,
- user_data,
- param_array.borrowReference());
- }
- inline void XmlRpcClient::event_loop_asynch(unsigned long milliseconds)
- {
- xmlrpc_client_event_loop_finish_asynch_timeout(milliseconds);
- }
- //=========================================================================
- // XmlRpcClient Methods
- //=========================================================================
- // These are inline for now, so we don't need to screw with linker issues
- // and build a separate client library.
- inline XmlRpcClient::XmlRpcClient (const XmlRpcClient& client)
- : mServerUrl(client.mServerUrl)
- {
- }
- inline XmlRpcClient& XmlRpcClient::operator= (const XmlRpcClient& client) {
- if (this != &client)
- mServerUrl = client.mServerUrl;
- return *this;
- }
- inline void XmlRpcClient::Initialize (string appname, string appversion) {
- xmlrpc_client_init(XMLRPC_CLIENT_NO_FLAGS,
- appname.c_str(),
- appversion.c_str());
- }
- inline void XmlRpcClient::Terminate (void) {
- xmlrpc_client_cleanup();
- }
- inline XmlRpcValue XmlRpcClient::call (string method_name,
- XmlRpcValue param_array)
- {
- XmlRpcEnv env;
- xmlrpc_value *result =
- xmlrpc_client_call_params(env,
- mServerUrl.c_str(),
- method_name.c_str(),
- param_array.borrowReference());
- env.throwIfFaultOccurred();
- return XmlRpcValue(result, XmlRpcValue::CONSUME_REFERENCE);
- }
- //=========================================================================
- // XmlRpcGenSrv
- //=========================================================================
- class XmlRpcGenSrv {
- private:
- xmlrpc_registry* mRegistry;
- xmlrpc_mem_block* alloc (XmlRpcEnv& env, const string& body) const;
- public:
- XmlRpcGenSrv (int flags);
- ~XmlRpcGenSrv (void);
- xmlrpc_registry* getRegistry (void) const;
- XmlRpcGenSrv& addMethod (const string& name,
- xmlrpc_method method,
- void *data);
- XmlRpcGenSrv& addMethod (const string& name,
- xmlrpc_method method,
- void* data,
- const string& signature,
- const string& help);
- string handle (const string& body) const;
- };
- inline XmlRpcGenSrv::XmlRpcGenSrv (int flags) {
- XmlRpcEnv env;
- if (flags == flags){};
- mRegistry = xmlrpc_registry_new (env);
- env.throwIfFaultOccurred();
- }
- inline XmlRpcGenSrv::~XmlRpcGenSrv (void) {
- xmlrpc_registry_free (mRegistry);
- }
- inline xmlrpc_registry* XmlRpcGenSrv::getRegistry () const {
- return mRegistry;
- }
- #undef XMLRPC_NO_ASSIGNMENT
- // Copyright (C) 2001 by Eric Kidd. All rights reserved.
- //
- // Redistribution and use in source and binary forms, with or without
- // modification, are permitted provided that the following conditions
- // are met:
- // 1. Redistributions of source code must retain the above copyright
- // notice, this list of conditions and the following disclaimer.
- // 2. Redistributions in binary form must reproduce the above copyright
- // notice, this list of conditions and the following disclaimer in the
- // documentation and/or other materials provided with the distribution.
- // 3. The name of the author may not be used to endorse or promote products
- // derived from this software without specific prior written permission.
- //
- // THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- // ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- // SUCH DAMAGE.
- #endif /* _XMLRPCCPP_H_ */
|