| |
| #ifndef _XMLRPCVALUE_H_ |
| #define _XMLRPCVALUE_H_ |
| // |
| // XmlRpc++ Copyright (c) 2002-2003 by Chris Morley |
| // |
| #if defined(_MSC_VER) |
| # pragma warning(disable:4786) // identifier was truncated in debug info |
| #endif |
| |
| #ifndef MAKEDEPEND |
| # include <map> |
| # include <string> |
| # include <vector> |
| # include <time.h> |
| #endif |
| |
| namespace XmlRpc { |
| |
| //! RPC method arguments and results are represented by Values |
| // should probably refcount them... |
| class XmlRpcValue { |
| public: |
| |
| |
| enum Type { |
| TypeInvalid, |
| TypeBoolean, |
| TypeInt, |
| TypeDouble, |
| TypeString, |
| TypeDateTime, |
| TypeBase64, |
| TypeArray, |
| TypeStruct |
| }; |
| |
| // Non-primitive types |
| typedef std::vector<char> BinaryData; |
| typedef std::vector<XmlRpcValue> ValueArray; |
| typedef std::map<std::string, XmlRpcValue> ValueStruct; |
| |
| |
| //! Constructors |
| XmlRpcValue() : _type(TypeInvalid) { _value.asBinary = 0; } |
| XmlRpcValue(bool value) : _type(TypeBoolean) { _value.asBool = value; } |
| XmlRpcValue(int value) : _type(TypeInt) { _value.asInt = value; } |
| XmlRpcValue(double value) : _type(TypeDouble) { _value.asDouble = value; } |
| |
| XmlRpcValue(std::string const& value) : _type(TypeString) |
| { _value.asString = new std::string(value); } |
| |
| XmlRpcValue(const char* value) : _type(TypeString) |
| { _value.asString = new std::string(value); } |
| |
| XmlRpcValue(struct tm* value) : _type(TypeDateTime) |
| { _value.asTime = new struct tm(*value); } |
| |
| |
| XmlRpcValue(void* value, int nBytes) : _type(TypeBase64) |
| { |
| _value.asBinary = new BinaryData((char*)value, ((char*)value)+nBytes); |
| } |
| |
| //! Construct from xml, beginning at *offset chars into the string, updates offset |
| XmlRpcValue(std::string const& xml, int* offset) : _type(TypeInvalid) |
| { if ( ! fromXml(xml,offset)) _type = TypeInvalid; } |
| |
| //! Copy |
| XmlRpcValue(XmlRpcValue const& rhs) : _type(TypeInvalid) { *this = rhs; } |
| |
| //! Destructor (make virtual if you want to subclass) |
| /*virtual*/ ~XmlRpcValue() { invalidate(); } |
| |
| //! Erase the current value |
| void clear() { invalidate(); } |
| |
| // Operators |
| XmlRpcValue& operator=(XmlRpcValue const& rhs); |
| XmlRpcValue& operator=(int const& rhs) { return operator=(XmlRpcValue(rhs)); } |
| XmlRpcValue& operator=(double const& rhs) { return operator=(XmlRpcValue(rhs)); } |
| XmlRpcValue& operator=(const char* rhs) { return operator=(XmlRpcValue(std::string(rhs))); } |
| |
| bool operator==(XmlRpcValue const& other) const; |
| bool operator!=(XmlRpcValue const& other) const; |
| |
| operator bool&() { assertTypeOrInvalid(TypeBoolean); return _value.asBool; } |
| operator int&() { assertTypeOrInvalid(TypeInt); return _value.asInt; } |
| operator double&() { assertTypeOrInvalid(TypeDouble); return _value.asDouble; } |
| operator std::string&() { assertTypeOrInvalid(TypeString); return *_value.asString; } |
| operator BinaryData&() { assertTypeOrInvalid(TypeBase64); return *_value.asBinary; } |
| operator struct tm&() { assertTypeOrInvalid(TypeDateTime); return *_value.asTime; } |
| |
| XmlRpcValue const& operator[](int i) const { assertArray(i+1); return _value.asArray->at(i); } |
| XmlRpcValue& operator[](int i) { assertArray(i+1); return _value.asArray->at(i); } |
| |
| XmlRpcValue& operator[](std::string const& k) { assertStruct(); return (*_value.asStruct)[k]; } |
| XmlRpcValue& operator[](const char* k) { assertStruct(); std::string s(k); return (*_value.asStruct)[s]; } |
| |
| // Accessors |
| //! Return true if the value has been set to something. |
| bool valid() const { return _type != TypeInvalid; } |
| |
| //! Return the type of the value stored. \see Type. |
| Type const &getType() const { return _type; } |
| |
| //! Return the size for string, base64, array, and struct values. |
| int size() const; |
| |
| //! Specify the size for array values. Array values will grow beyond this size if needed. |
| void setSize(int size) { assertArray(size); } |
| |
| //! Check for the existence of a struct member by name. |
| bool hasMember(const std::string& name) const; |
| |
| //! Decode xml. Destroys any existing value. |
| bool fromXml(std::string const& valueXml, int* offset); |
| |
| //! Encode the Value in xml |
| std::string toXml() const; |
| |
| //! Write the value (no xml encoding) |
| std::ostream& write(std::ostream& os) const; |
| |
| // Formatting |
| //! Return the format used to write double values. |
| static std::string const& getDoubleFormat() { return _doubleFormat; } |
| |
| //! Specify the format used to write double values. |
| static void setDoubleFormat(const char* f) { _doubleFormat = f; } |
| |
| |
| protected: |
| // Clean up |
| void invalidate(); |
| |
| // Type checking |
| void assertTypeOrInvalid(Type t); |
| void assertArray(int size) const; |
| void assertArray(int size); |
| void assertStruct(); |
| |
| // XML decoding |
| bool boolFromXml(std::string const& valueXml, int* offset); |
| bool intFromXml(std::string const& valueXml, int* offset); |
| bool doubleFromXml(std::string const& valueXml, int* offset); |
| bool stringFromXml(std::string const& valueXml, int* offset); |
| bool timeFromXml(std::string const& valueXml, int* offset); |
| bool binaryFromXml(std::string const& valueXml, int* offset); |
| bool arrayFromXml(std::string const& valueXml, int* offset); |
| bool structFromXml(std::string const& valueXml, int* offset); |
| |
| // XML encoding |
| std::string boolToXml() const; |
| std::string intToXml() const; |
| std::string doubleToXml() const; |
| std::string stringToXml() const; |
| std::string timeToXml() const; |
| std::string binaryToXml() const; |
| std::string arrayToXml() const; |
| std::string structToXml() const; |
| |
| // Format strings |
| static std::string _doubleFormat; |
| |
| // Type tag and values |
| Type _type; |
| |
| // At some point I will split off Arrays and Structs into |
| // separate ref-counted objects for more efficient copying. |
| union { |
| bool asBool; |
| int asInt; |
| double asDouble; |
| struct tm* asTime; |
| std::string* asString; |
| BinaryData* asBinary; |
| ValueArray* asArray; |
| ValueStruct* asStruct; |
| } _value; |
| |
| }; |
| } // namespace XmlRpc |
| |
| |
| std::ostream& operator<<(std::ostream& os, XmlRpc::XmlRpcValue& v); |
| |
| |
| #endif // _XMLRPCVALUE_H_ |