Home | History | Annotate | Download | only in src
      1 
      2 #ifndef _XMLRPCVALUE_H_
      3 #define _XMLRPCVALUE_H_
      4 //
      5 // XmlRpc++ Copyright (c) 2002-2003 by Chris Morley
      6 //
      7 #if defined(_MSC_VER)
      8 # pragma warning(disable:4786)    // identifier was truncated in debug info
      9 #endif
     10 
     11 #ifndef MAKEDEPEND
     12 # include <map>
     13 # include <string>
     14 # include <vector>
     15 # include <time.h>
     16 #endif
     17 
     18 namespace XmlRpc {
     19 
     20   //! RPC method arguments and results are represented by Values
     21   //   should probably refcount them...
     22   class XmlRpcValue {
     23   public:
     24 
     25 
     26     enum Type {
     27       TypeInvalid,
     28       TypeBoolean,
     29       TypeInt,
     30       TypeDouble,
     31       TypeString,
     32       TypeDateTime,
     33       TypeBase64,
     34       TypeArray,
     35       TypeStruct,
     36       TypeNil
     37     };
     38 
     39     // Non-primitive types
     40     typedef std::vector<char> BinaryData;
     41     typedef std::vector<XmlRpcValue> ValueArray;
     42     typedef std::map<std::string, XmlRpcValue> ValueStruct;
     43 
     44 
     45     //! Constructors
     46     XmlRpcValue() : _type(TypeInvalid) { _value.asBinary = 0; }
     47     XmlRpcValue(bool value) : _type(TypeBoolean) { _value.asBool = value; }
     48     XmlRpcValue(int value)  : _type(TypeInt) { _value.asInt = value; }
     49     XmlRpcValue(double value)  : _type(TypeDouble) { _value.asDouble = value; }
     50 
     51     XmlRpcValue(std::string const& value) : _type(TypeString)
     52     { _value.asString = new std::string(value); }
     53 
     54     XmlRpcValue(const char* value)  : _type(TypeString)
     55     { _value.asString = new std::string(value); }
     56 
     57     XmlRpcValue(struct tm* value)  : _type(TypeDateTime)
     58     { _value.asTime = new struct tm(*value); }
     59 
     60 
     61     XmlRpcValue(void* value, int nBytes)  : _type(TypeBase64)
     62     {
     63       _value.asBinary = new BinaryData((char*)value, ((char*)value)+nBytes);
     64     }
     65 
     66     //! Construct from xml, beginning at *offset chars into the string, updates offset
     67     XmlRpcValue(std::string const& xml, int* offset) : _type(TypeInvalid)
     68     { if ( ! fromXml(xml,offset)) _type = TypeInvalid; }
     69 
     70     //! Copy
     71     XmlRpcValue(XmlRpcValue const& rhs) : _type(TypeInvalid) { *this = rhs; }
     72 
     73     //! Destructor (make virtual if you want to subclass)
     74     /*virtual*/ ~XmlRpcValue() { invalidate(); }
     75 
     76     //! Erase the current value
     77     void clear() { invalidate(); }
     78 
     79     // Operators
     80     XmlRpcValue& operator=(XmlRpcValue const& rhs);
     81     XmlRpcValue& operator=(int const& rhs) { return operator=(XmlRpcValue(rhs)); }
     82     XmlRpcValue& operator=(double const& rhs) { return operator=(XmlRpcValue(rhs)); }
     83     XmlRpcValue& operator=(const char* rhs) { return operator=(XmlRpcValue(std::string(rhs))); }
     84 
     85     bool operator==(XmlRpcValue const& other) const;
     86     bool operator!=(XmlRpcValue const& other) const;
     87 
     88     operator bool&()          { assertTypeOrInvalid(TypeBoolean); return _value.asBool; }
     89     operator int&()           { assertTypeOrInvalid(TypeInt); return _value.asInt; }
     90     operator double&()        { assertTypeOrInvalid(TypeDouble); return _value.asDouble; }
     91     operator std::string&()   { assertTypeOrInvalid(TypeString); return *_value.asString; }
     92     operator BinaryData&()    { assertTypeOrInvalid(TypeBase64); return *_value.asBinary; }
     93     operator struct tm&()     { assertTypeOrInvalid(TypeDateTime); return *_value.asTime; }
     94 
     95     XmlRpcValue const& operator[](int i) const { assertArray(i+1); return _value.asArray->at(i); }
     96     XmlRpcValue& operator[](int i)             { assertArray(i+1); return _value.asArray->at(i); }
     97 
     98     XmlRpcValue& operator[](std::string const& k) { assertStruct(); return (*_value.asStruct)[k]; }
     99     XmlRpcValue& operator[](const char* k) { assertStruct(); std::string s(k); return (*_value.asStruct)[s]; }
    100 
    101     // Accessors
    102     //! Return true if the value has been set to something.
    103     bool valid() const { return _type != TypeInvalid; }
    104 
    105     //! Return the type of the value stored. \see Type.
    106     Type const &getType() const { return _type; }
    107 
    108     //! Return the size for string, base64, array, and struct values.
    109     int size() const;
    110 
    111     //! Specify the size for array values. Array values will grow beyond this size if needed.
    112     void setSize(int size)    { assertArray(size); }
    113 
    114     //! Check for the existence of a struct member by name.
    115     bool hasMember(const std::string& name) const;
    116 
    117     //! Decode xml. Destroys any existing value.
    118     bool fromXml(std::string const& valueXml, int* offset);
    119 
    120     //! Encode the Value in xml
    121     std::string toXml() const;
    122 
    123     //! Write the value (no xml encoding)
    124     std::ostream& write(std::ostream& os) const;
    125 
    126     // Formatting
    127     //! Return the format used to write double values.
    128     static std::string const& getDoubleFormat() { return _doubleFormat; }
    129 
    130     //! Specify the format used to write double values.
    131     static void setDoubleFormat(const char* f) { _doubleFormat = f; }
    132 
    133     //! Set the value type to Nil. This value will be encoded as <nil/> xml tag.
    134     void setToNil() { assertTypeOrInvalid(TypeNil); }
    135 
    136   protected:
    137     // Clean up
    138     void invalidate();
    139 
    140     // Type checking
    141     void assertTypeOrInvalid(Type t);
    142     void assertArray(int size) const;
    143     void assertArray(int size);
    144     void assertStruct();
    145 
    146     // XML decoding
    147     bool nilFromXml(std::string const& valueXml, int* offset);
    148     bool boolFromXml(std::string const& valueXml, int* offset);
    149     bool intFromXml(std::string const& valueXml, int* offset);
    150     bool doubleFromXml(std::string const& valueXml, int* offset);
    151     bool stringFromXml(std::string const& valueXml, int* offset);
    152     bool timeFromXml(std::string const& valueXml, int* offset);
    153     bool binaryFromXml(std::string const& valueXml, int* offset);
    154     bool arrayFromXml(std::string const& valueXml, int* offset);
    155     bool structFromXml(std::string const& valueXml, int* offset);
    156 
    157     // XML encoding
    158     std::string nilToXml() const;
    159     std::string boolToXml() const;
    160     std::string intToXml() const;
    161     std::string doubleToXml() const;
    162     std::string stringToXml() const;
    163     std::string timeToXml() const;
    164     std::string binaryToXml() const;
    165     std::string arrayToXml() const;
    166     std::string structToXml() const;
    167 
    168     // Format strings
    169     static std::string _doubleFormat;
    170 
    171     // Type tag and values
    172     Type _type;
    173 
    174     // At some point I will split off Arrays and Structs into
    175     // separate ref-counted objects for more efficient copying.
    176     union {
    177       bool          asBool;
    178       int           asInt;
    179       double        asDouble;
    180       struct tm*    asTime;
    181       std::string*  asString;
    182       BinaryData*   asBinary;
    183       ValueArray*   asArray;
    184       ValueStruct*  asStruct;
    185     } _value;
    186 
    187   };
    188 } // namespace XmlRpc
    189 
    190 
    191 std::ostream& operator<<(std::ostream& os, XmlRpc::XmlRpcValue& v);
    192 
    193 
    194 #endif // _XMLRPCVALUE_H_
    195