14e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
24e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#ifndef _XMLRPCVALUE_H_
34e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#define _XMLRPCVALUE_H_
44e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius//
54e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius// XmlRpc++ Copyright (c) 2002-2003 by Chris Morley
64e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius//
74e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#if defined(_MSC_VER)
84e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius# pragma warning(disable:4786)    // identifier was truncated in debug info
94e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#endif
104e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
114e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#ifndef MAKEDEPEND
124e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius# include <map>
134e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius# include <string>
144e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius# include <vector>
154e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius# include <time.h>
164e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#endif
174e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
184e2ea8184cc1f9609f1f1251394316629a108a78Roshan Piusnamespace XmlRpc {
194e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
204e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  //! RPC method arguments and results are represented by Values
214e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  //   should probably refcount them...
224e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  class XmlRpcValue {
234e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  public:
244e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
254e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
264e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    enum Type {
274e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius      TypeInvalid,
284e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius      TypeBoolean,
294e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius      TypeInt,
304e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius      TypeDouble,
314e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius      TypeString,
324e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius      TypeDateTime,
334e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius      TypeBase64,
344e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius      TypeArray,
35b0b71ed8b630bbf1b94f0be0c4030d8488b3f8b7Roshan Pius      TypeStruct,
36b0b71ed8b630bbf1b94f0be0c4030d8488b3f8b7Roshan Pius      TypeNil
374e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    };
384e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
394e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    // Non-primitive types
404e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    typedef std::vector<char> BinaryData;
414e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    typedef std::vector<XmlRpcValue> ValueArray;
424e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    typedef std::map<std::string, XmlRpcValue> ValueStruct;
434e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
444e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
454e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    //! Constructors
464e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    XmlRpcValue() : _type(TypeInvalid) { _value.asBinary = 0; }
474e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    XmlRpcValue(bool value) : _type(TypeBoolean) { _value.asBool = value; }
484e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    XmlRpcValue(int value)  : _type(TypeInt) { _value.asInt = value; }
494e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    XmlRpcValue(double value)  : _type(TypeDouble) { _value.asDouble = value; }
504e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
514e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    XmlRpcValue(std::string const& value) : _type(TypeString)
524e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    { _value.asString = new std::string(value); }
534e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
544e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    XmlRpcValue(const char* value)  : _type(TypeString)
554e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    { _value.asString = new std::string(value); }
564e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
574e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    XmlRpcValue(struct tm* value)  : _type(TypeDateTime)
584e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    { _value.asTime = new struct tm(*value); }
594e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
604e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
614e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    XmlRpcValue(void* value, int nBytes)  : _type(TypeBase64)
624e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    {
634e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius      _value.asBinary = new BinaryData((char*)value, ((char*)value)+nBytes);
644e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    }
654e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
664e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    //! Construct from xml, beginning at *offset chars into the string, updates offset
674e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    XmlRpcValue(std::string const& xml, int* offset) : _type(TypeInvalid)
684e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    { if ( ! fromXml(xml,offset)) _type = TypeInvalid; }
694e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
704e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    //! Copy
714e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    XmlRpcValue(XmlRpcValue const& rhs) : _type(TypeInvalid) { *this = rhs; }
724e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
734e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    //! Destructor (make virtual if you want to subclass)
744e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    /*virtual*/ ~XmlRpcValue() { invalidate(); }
754e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
764e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    //! Erase the current value
774e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    void clear() { invalidate(); }
784e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
794e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    // Operators
804e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    XmlRpcValue& operator=(XmlRpcValue const& rhs);
814e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    XmlRpcValue& operator=(int const& rhs) { return operator=(XmlRpcValue(rhs)); }
824e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    XmlRpcValue& operator=(double const& rhs) { return operator=(XmlRpcValue(rhs)); }
834e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    XmlRpcValue& operator=(const char* rhs) { return operator=(XmlRpcValue(std::string(rhs))); }
844e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
854e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    bool operator==(XmlRpcValue const& other) const;
864e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    bool operator!=(XmlRpcValue const& other) const;
874e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
884e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    operator bool&()          { assertTypeOrInvalid(TypeBoolean); return _value.asBool; }
894e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    operator int&()           { assertTypeOrInvalid(TypeInt); return _value.asInt; }
904e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    operator double&()        { assertTypeOrInvalid(TypeDouble); return _value.asDouble; }
914e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    operator std::string&()   { assertTypeOrInvalid(TypeString); return *_value.asString; }
924e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    operator BinaryData&()    { assertTypeOrInvalid(TypeBase64); return *_value.asBinary; }
934e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    operator struct tm&()     { assertTypeOrInvalid(TypeDateTime); return *_value.asTime; }
944e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
954e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    XmlRpcValue const& operator[](int i) const { assertArray(i+1); return _value.asArray->at(i); }
964e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    XmlRpcValue& operator[](int i)             { assertArray(i+1); return _value.asArray->at(i); }
974e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
984e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    XmlRpcValue& operator[](std::string const& k) { assertStruct(); return (*_value.asStruct)[k]; }
994e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    XmlRpcValue& operator[](const char* k) { assertStruct(); std::string s(k); return (*_value.asStruct)[s]; }
1004e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
1014e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    // Accessors
1024e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    //! Return true if the value has been set to something.
1034e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    bool valid() const { return _type != TypeInvalid; }
1044e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
1054e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    //! Return the type of the value stored. \see Type.
1064e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    Type const &getType() const { return _type; }
1074e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
1084e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    //! Return the size for string, base64, array, and struct values.
1094e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    int size() const;
1104e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
1114e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    //! Specify the size for array values. Array values will grow beyond this size if needed.
1124e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    void setSize(int size)    { assertArray(size); }
1134e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
1144e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    //! Check for the existence of a struct member by name.
1154e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    bool hasMember(const std::string& name) const;
1164e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
1174e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    //! Decode xml. Destroys any existing value.
1184e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    bool fromXml(std::string const& valueXml, int* offset);
1194e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
1204e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    //! Encode the Value in xml
1214e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    std::string toXml() const;
1224e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
1234e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    //! Write the value (no xml encoding)
1244e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    std::ostream& write(std::ostream& os) const;
1254e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
1264e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    // Formatting
1274e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    //! Return the format used to write double values.
1284e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    static std::string const& getDoubleFormat() { return _doubleFormat; }
1294e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
1304e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    //! Specify the format used to write double values.
1314e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    static void setDoubleFormat(const char* f) { _doubleFormat = f; }
1324e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
133b0b71ed8b630bbf1b94f0be0c4030d8488b3f8b7Roshan Pius    //! Set the value type to Nil. This value will be encoded as <nil/> xml tag.
134b0b71ed8b630bbf1b94f0be0c4030d8488b3f8b7Roshan Pius    void setToNil() { assertTypeOrInvalid(TypeNil); }
1354e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
1364e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  protected:
1374e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    // Clean up
1384e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    void invalidate();
1394e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
1404e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    // Type checking
1414e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    void assertTypeOrInvalid(Type t);
1424e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    void assertArray(int size) const;
1434e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    void assertArray(int size);
1444e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    void assertStruct();
1454e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
1464e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    // XML decoding
147b0b71ed8b630bbf1b94f0be0c4030d8488b3f8b7Roshan Pius    bool nilFromXml(std::string const& valueXml, int* offset);
1484e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    bool boolFromXml(std::string const& valueXml, int* offset);
1494e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    bool intFromXml(std::string const& valueXml, int* offset);
1504e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    bool doubleFromXml(std::string const& valueXml, int* offset);
1514e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    bool stringFromXml(std::string const& valueXml, int* offset);
1524e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    bool timeFromXml(std::string const& valueXml, int* offset);
1534e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    bool binaryFromXml(std::string const& valueXml, int* offset);
1544e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    bool arrayFromXml(std::string const& valueXml, int* offset);
1554e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    bool structFromXml(std::string const& valueXml, int* offset);
1564e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
1574e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    // XML encoding
158b0b71ed8b630bbf1b94f0be0c4030d8488b3f8b7Roshan Pius    std::string nilToXml() const;
1594e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    std::string boolToXml() const;
1604e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    std::string intToXml() const;
1614e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    std::string doubleToXml() const;
1624e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    std::string stringToXml() const;
1634e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    std::string timeToXml() const;
1644e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    std::string binaryToXml() const;
1654e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    std::string arrayToXml() const;
1664e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    std::string structToXml() const;
1674e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
1684e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    // Format strings
1694e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    static std::string _doubleFormat;
1704e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
1714e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    // Type tag and values
1724e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    Type _type;
1734e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
1744e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    // At some point I will split off Arrays and Structs into
1754e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    // separate ref-counted objects for more efficient copying.
1764e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    union {
1774e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius      bool          asBool;
1784e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius      int           asInt;
1794e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius      double        asDouble;
1804e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius      struct tm*    asTime;
1814e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius      std::string*  asString;
1824e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius      BinaryData*   asBinary;
1834e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius      ValueArray*   asArray;
1844e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius      ValueStruct*  asStruct;
1854e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius    } _value;
1864e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
1874e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius  };
1884e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius} // namespace XmlRpc
1894e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
1904e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
1914e2ea8184cc1f9609f1f1251394316629a108a78Roshan Piusstd::ostream& operator<<(std::ostream& os, XmlRpc::XmlRpcValue& v);
1924e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
1934e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius
1944e2ea8184cc1f9609f1f1251394316629a108a78Roshan Pius#endif // _XMLRPCVALUE_H_
195