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 XmlRpcValue()46 XmlRpcValue() : _type(TypeInvalid) { _value.asBinary = 0; } XmlRpcValue(bool value)47 XmlRpcValue(bool value) : _type(TypeBoolean) { _value.asBool = value; } XmlRpcValue(int value)48 XmlRpcValue(int value) : _type(TypeInt) { _value.asInt = value; } XmlRpcValue(double value)49 XmlRpcValue(double value) : _type(TypeDouble) { _value.asDouble = value; } 50 XmlRpcValue(std::string const & value)51 XmlRpcValue(std::string const& value) : _type(TypeString) 52 { _value.asString = new std::string(value); } 53 XmlRpcValue(const char * value)54 XmlRpcValue(const char* value) : _type(TypeString) 55 { _value.asString = new std::string(value); } 56 XmlRpcValue(struct tm * value)57 XmlRpcValue(struct tm* value) : _type(TypeDateTime) 58 { _value.asTime = new struct tm(*value); } 59 60 XmlRpcValue(void * value,int nBytes)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 XmlRpcValue(std::string const & xml,int * offset)67 XmlRpcValue(std::string const& xml, int* offset) : _type(TypeInvalid) 68 { if ( ! fromXml(xml,offset)) _type = TypeInvalid; } 69 70 //! Copy XmlRpcValue(XmlRpcValue const & rhs)71 XmlRpcValue(XmlRpcValue const& rhs) : _type(TypeInvalid) { *this = rhs; } 72 73 //! Destructor (make virtual if you want to subclass) ~XmlRpcValue()74 /*virtual*/ ~XmlRpcValue() { invalidate(); } 75 76 //! Erase the current value clear()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. valid()103 bool valid() const { return _type != TypeInvalid; } 104 105 //! Return the type of the value stored. \see Type. getType()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. setSize(int size)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. getDoubleFormat()128 static std::string const& getDoubleFormat() { return _doubleFormat; } 129 130 //! Specify the format used to write double values. setDoubleFormat(const char * f)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. setToNil()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