xmlrpc.h

Go to the documentation of this file.
00001 
00002  //
00003  // XMLStorage XML-RPC extension
00004  //
00005  // Copyright (c) 2009 Martin Fuchs <martin-fuchs@gmx.net>
00006  //
00007 
00008 
00009 /*
00010 
00011   All rights reserved.
00012 
00013   Redistribution and use in source and binary forms, with or without
00014   modification, are permitted provided that the following conditions are met:
00015 
00016   * Redistributions of source code must retain the above copyright
00017     notice, this list of conditions and the following disclaimer.
00018   * Redistributions in binary form must reproduce the above copyright
00019     notice, this list of conditions and the following disclaimer in
00020     the documentation and/or other materials provided with the
00021     distribution.
00022 
00023   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00024   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00025   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00026   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00027   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00028   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00029   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00030   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00031   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00032   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00033   POSSIBILITY OF SUCH DAMAGE.
00034 
00035 */
00036 
00037 #pragma once
00038 
00039 #ifndef __XMLRPC_H
00040 
00041 
00042 #if _MSC_VER>=1400 // VS2005 or higher
00043 // define _CRT_SECURE_CPP_OVERLOAD_... before including any system header file to be compatible to xmlstorage.h
00044 #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES         1
00045 #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT   1
00046 #define _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES           1
00047 #else
00048 #endif
00049 
00050 #ifndef _MSC_VER
00051 #define _strnicmp strncasecmp
00052 #endif
00053 
00054 #ifdef _WIN32
00055 #include <winsock2.h>
00056 #include <ws2tcpip.h>   // getaddrinfo()
00057 #pragma comment(lib, "ws2_32")
00058 #else
00059 #include <netdb.h>
00060 #include <errno.h>
00061 #endif
00062 
00063 #include <xmlstorage.h> // define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES before including any other system header file
00064 using namespace XMLStorage;
00065 
00066 #ifndef __STDC_WANT_SECURE_LIB__
00067 #define sscanf_s sscanf // beware: format strings for sscanf_s() and sscanf() are only identically, if no string buffers are used to return strings!
00068 #endif
00069 
00070 using namespace std;
00071 
00072 #include <assert.h>
00073 
00074 
00075 struct Exception : public exception
00076 {
00077     Exception(const char* msg, int code=0)
00078      :  _msg(msg),
00079         _code(code)
00080     {
00081     }
00082 
00083     ~Exception() throw()
00084     {
00085     }
00086 
00087     const char* what() const throw()
00088     {
00089         return _msg.c_str();
00090     }
00091 
00092 protected:
00093     string  _msg;
00094     int _code;
00095 
00096     Exception(int code=0)
00097      :  _code(code)
00098     {
00099     }
00100 };
00101 
00102 
00103 #ifdef _WIN32
00104 
00105  // Exception for Windows errors
00106 struct WE : public Exception
00107 {
00108     WE(DWORD code)
00109      :  Exception(code)
00110     {
00111         LPSTR buffer;
00112 
00113         if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
00114             0, code, MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), (LPSTR)&buffer, 0, NULL)) {
00115             _msg = buffer;
00116             LocalFree(buffer);
00117         } else {
00118             char b[64];
00119             sprintf(b, "unknown error 0x%08X", code);
00120             _msg = b;
00121         }
00122     }
00123 };
00124 
00125  // Exception for the last operating system error code
00126 struct LWE : public WE
00127 {
00128     LWE()
00129      : WE(GetLastError())
00130     {
00131     }
00132 };
00133 
00134  // WINSOCK exception
00135 struct LWSE : public WE
00136 {
00137     LWSE()
00138      : WE(WSAGetLastError())
00139     {
00140     }
00141 };
00142 
00143 #else
00144 
00145  // operating system error exception
00146 struct LWSE : public Exception
00147 {
00148     LWSE()
00149      :  Exception(errno)
00150     {
00151         _msg = strerror(_code);
00152     }
00153 };
00154 
00155 #endif // _WIN32
00156 
00157 
00158  // ISO 8601 conforming date
00159 struct ISODate
00160 {
00161     ISODate();  // initialized with current date+time
00162     ISODate(const char* s);
00163 
00164     string  str() const;
00165     long    diff(const ISODate& other) const;
00166 
00167     int _year;
00168     int _month;
00169     int _day;
00170 
00171     int _hour;
00172     int _minute;
00173     int _second;
00174 };
00175 
00176 extern char* base64_encode(const void* buf, size_t size);
00177 extern void* base64_decode(const char* s, size_t& data_len);
00178 
00179  // BASE64 encoded binary
00180 struct Binary
00181 {
00182     Binary(const void* buffer, size_t len);
00183     Binary(const char* base64);
00184     Binary(const Binary& other);
00185     ~Binary() {free(_buffer);}
00186 
00187     string str() const;
00188 
00189     void* _buffer;
00190     size_t  _len;
00191 };
00192 
00193 
00194 struct XMLRPCArray : public list<string>
00195 {
00196     XMLRPCArray() {}
00197     XMLRPCArray(const_XMLPos pos);
00198 };
00199 
00200 struct XMLRPCStruct : public map<string, string>
00201 {
00202     XMLRPCStruct() {}
00203     XMLRPCStruct(const XMLNode& node);
00204 };
00205 
00206 
00207  // Exception for failures received from the server
00208 struct XMLRPCFault : public Exception
00209 {
00210     XMLRPCFault(int faultCode, const string& faultString)
00211      :  Exception(faultCode)
00212     {
00213         ostringstream buffer;
00214 
00215         buffer << "XMLRPCFault " << _code << ": " << faultString;
00216 
00217         _msg = buffer.str();
00218     }
00219 };
00220 
00221 
00222 enum XMLRPC_TYPE
00223 {
00224     XRT_VOID,
00225     XRT_INT, XRT_DOUBLE, XRT_BOOLEAN, XRT_STRING,
00226     XRT_DATE, XRT_BINARY, XRT_ARRAY, XRT_STRUCT
00227 };
00228 
00229 typedef list<XMLRPC_TYPE> TypeList;
00230 
00231 
00232 struct XMLRPCParser
00233 {
00234     XMLRPCParser(const string& xml_str, const string& keyword);
00235 
00236     string  get_any();
00237     int     get_int();
00238     double  get_double();
00239     bool    get_bool();
00240     string  get_string();
00241     ISODate get_date();
00242     Binary  get_binary();
00243     XMLRPCArray get_array();
00244     XMLRPCStruct get_struct();
00245 
00246     bool    more_parameters() const;
00247     XMLRPC_TYPE get_next_type() const;
00248     size_t  get_parameter_types(TypeList& types) const;
00249 
00250 protected:
00251     XMLDoc  _doc;
00252     XMLPos  _pos;
00253     size_t  _value_cnt;
00254 
00255 private:
00256     bool    next_parameter();
00257 
00258     static XMLRPC_TYPE get_param_type(const XMLNode* pNode);
00259 };
00260 
00261  // read single values from the XML data
00262 struct XMLRPCValue
00263 {
00264     static string   get_any(const_XMLPos pos);
00265     static int      get_int(const_XMLPos pos);
00266     static double   get_double(const_XMLPos pos);
00267     static bool     get_bool(const_XMLPos pos);
00268     static string   get_string(const_XMLPos pos);
00269     static ISODate  get_date(const_XMLPos pos);
00270     static Binary   get_binary(const_XMLPos pos);
00271     static XMLRPCArray get_array(const_XMLPos pos);
00272     static XMLRPCStruct get_struct(const_XMLPos pos);
00273 };
00274 
00275 
00276  // decode the response received from the server
00277 struct XMLRPCResult : public XMLRPCParser
00278 {
00279     XMLRPCResult(const string& xml_str);
00280 
00281     string  _fault;
00282 };
00283 
00284 
00285 struct XMLRPCWriter
00286 {
00287     XMLRPCWriter() : _writer(_buffer, PRETTY_PLAIN), _params(0) {}
00288 
00289     string  flush();
00290 
00291 protected:
00292     void    write_string_param(const string& value);
00293     void    write_param(const string& type, const string& value);
00294     void    write_param(const XMLRPCArray& arr);
00295     void    write_param(const XMLRPCStruct& str);
00296     void    write_struct(const XMLRPCStruct& str, const string& keyword);
00297 
00298     ostringstream _buffer;
00299     XMLWriter   _writer;
00300     int _params;
00301 };
00302 
00303 
00304  // XMLRPCCall is used for calling a XML-RPC function from the client.
00305 struct XMLRPCCall : public XMLRPCWriter
00306 {
00307     XMLRPCCall(const char* name);
00308 
00309     XMLRPCCall& operator%(int i4)                   {write_param("i4", XMLInt(i4));                 return *this;}
00310     XMLRPCCall& operator%(double d)                 {write_param("double", XMLDouble(d));           return *this;}
00311     XMLRPCCall& operator%(bool b)                   {write_param("boolean", b? "1": "0");           return *this;}
00312     XMLRPCCall& operator%(const string& s)          {write_string_param(s);                         return *this;}
00313     XMLRPCCall& operator%(const char* s)            {write_string_param(s);                         return *this;}
00314     XMLRPCCall& operator%(const ISODate& date)      {write_param("dateTime.iso8601", date.str());   return *this;}
00315     XMLRPCCall& operator%(const Binary& bin)        {write_param("base64", bin.str());              return *this;}
00316     XMLRPCCall& operator%(const XMLRPCArray& arr)   {write_param(arr);}
00317     XMLRPCCall& operator%(const XMLRPCStruct& str)  {write_param(str);}
00318 
00319 private:
00320     void    init(const char* name);
00321 };
00322 
00323 
00324  // Decoding a request received from the client
00325 struct XMLRPCRequest : public XMLRPCParser
00326 {
00327     XMLRPCRequest(const string& xml_str);
00328 
00329     string  _method_name;
00330 };
00331 
00332  // XMLRPCResponse is used for creating a answer for a XML-RPC request in the server.
00333 struct XMLRPCResponse : public XMLRPCWriter
00334 {
00335     XMLRPCResponse()
00336     {
00337         init();
00338     }
00339 
00340     void    set_int(int i4)                     {write_param("i4", XMLInt(i4));}
00341     void    set_double(double d)                {write_param("double", XMLDouble(d));}
00342     void    set_bool(bool b)                    {write_param("boolean", b? "1": "0");}
00343     void    set_string(const string& s)         {write_string_param(s);}
00344     void    set_string(const char* s)           {write_string_param(s);}
00345     void    set_date(const ISODate& date)       {write_param("dateTime.iso8601", date.str());}
00346     void    set_binary(const Binary& bin)       {write_param("base64", bin.str());}
00347     void    set_array(const XMLRPCArray& arr)   {write_param(arr);}
00348     void    set_struct(const XMLRPCStruct& str) {write_param(str);}
00349 
00350     void    set_failure(int code, const string& message);
00351 
00352 private:
00353     void    init();
00354 };
00355 
00356 
00357 #define __XMLRPC_H
00358 #endif

Generated on Mon Aug 30 00:05:06 2010 for XMLStorage/C++ by  doxygen 1.5.4