00001 #ifndef _framing_FieldValue_h
00002 #define _framing_FieldValue_h
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "qpid/Exception.h"
00025 #include "amqp_types.h"
00026 #include "Buffer.h"
00027 #include "FieldTable.h"
00028
00029 #include "assert.h"
00030
00031 #include <iostream>
00032 #include <memory>
00033 #include <vector>
00034
00035 namespace qpid {
00036 namespace framing {
00037
00038
00044 class FieldValueException : public qpid::Exception {};
00045
00051 struct InvalidConversionException : public FieldValueException {
00052 InvalidConversionException() {}
00053 };
00054
00060 class FieldValue {
00061 public:
00062
00063
00064
00065 class Data {
00066 public:
00067 virtual ~Data() {};
00068 virtual uint32_t encodedSize() const = 0;
00069 virtual void encode(Buffer& buffer) = 0;
00070 virtual void decode(Buffer& buffer) = 0;
00071 virtual bool operator==(const Data&) const = 0;
00072
00073 virtual bool convertsToInt() const { return false; }
00074 virtual bool convertsToString() const { return false; }
00075 virtual int64_t getInt() const { throw InvalidConversionException();}
00076 virtual std::string getString() const { throw InvalidConversionException(); }
00077
00078 virtual void print(std::ostream& out) const = 0;
00079 };
00080
00081 FieldValue(): data(0) {};
00082
00083 void setType(uint8_t type);
00084 uint8_t getType();
00085 Data& getData() { return *data; }
00086 uint32_t encodedSize() const { return 1 + data->encodedSize(); };
00087 bool empty() const { return data.get() == 0; }
00088 void encode(Buffer& buffer);
00089 void decode(Buffer& buffer);
00090 bool operator==(const FieldValue&) const;
00091 bool operator!=(const FieldValue& v) const { return !(*this == v); }
00092
00093 void print(std::ostream& out) const;
00094
00095 template <typename T> bool convertsTo() const { return false; }
00096 template <typename T> T get() const { throw InvalidConversionException(); }
00097
00098 protected:
00099 FieldValue(uint8_t t, Data* d): typeOctet(t), data(d) {}
00100
00101 private:
00102 uint8_t typeOctet;
00103 std::auto_ptr<Data> data;
00104 };
00105
00106 template <>
00107 inline bool FieldValue::convertsTo<int>() const { return data->convertsToInt(); }
00108
00109 template <>
00110 inline bool FieldValue::convertsTo<int64_t>() const { return data->convertsToInt(); }
00111
00112 template <>
00113 inline bool FieldValue::convertsTo<std::string>() const { return data->convertsToString(); }
00114
00115 template <>
00116 inline int FieldValue::get<int>() const { return data->getInt(); }
00117
00118 template <>
00119 inline int64_t FieldValue::get<int64_t>() const { return data->getInt(); }
00120
00121 template <>
00122 inline std::string FieldValue::get<std::string>() const { return data->getString(); }
00123
00124 inline std::ostream& operator<<(std::ostream& out, const FieldValue& v) {
00125 v.print(out);
00126 return out;
00127 }
00128
00129 template <int width>
00130 class FixedWidthValue : public FieldValue::Data {
00131 uint8_t octets[width];
00132
00133 public:
00134 FixedWidthValue() {}
00135 FixedWidthValue(const uint8_t (&data)[width]) : octets(data) {}
00136 FixedWidthValue(const uint8_t* const data)
00137 {
00138 for (int i = 0; i < width; i++) octets[i] = data[i];
00139 }
00140 FixedWidthValue(uint64_t v)
00141 {
00142 for (int i = width; i > 1; --i) {
00143 octets[i-1] = (uint8_t) (0xFF & v); v >>= 8;
00144 }
00145 octets[0] = (uint8_t) (0xFF & v);
00146 }
00147 uint32_t encodedSize() const { return width; }
00148 void encode(Buffer& buffer) { buffer.putRawData(octets, width); }
00149 void decode(Buffer& buffer) { buffer.getRawData(octets, width); }
00150 bool operator==(const Data& d) const {
00151 const FixedWidthValue<width>* rhs = dynamic_cast< const FixedWidthValue<width>* >(&d);
00152 if (rhs == 0) return false;
00153 else return std::equal(&octets[0], &octets[width], &rhs->octets[0]);
00154 }
00155
00156 bool convertsToInt() const { return true; }
00157 int64_t getInt() const
00158 {
00159 int64_t v = 0;
00160 for (int i = 0; i < width-1; ++i) {
00161 v |= octets[i]; v <<= 8;
00162 }
00163 v |= octets[width-1];
00164 return v;
00165 }
00166 uint8_t* rawOctets() { return octets; }
00167
00168 void print(std::ostream& o) const { o << "F" << width << ":"; };
00169 };
00170
00171 template <>
00172 class FixedWidthValue<0> : public FieldValue::Data {
00173 public:
00174
00175 uint32_t encodedSize() const { return 0; }
00176 void encode(Buffer&) {};
00177 void decode(Buffer&) {};
00178 bool operator==(const Data& d) const {
00179 const FixedWidthValue<0>* rhs = dynamic_cast< const FixedWidthValue<0>* >(&d);
00180 return rhs != 0;
00181 }
00182 void print(std::ostream& o) const { o << "F0"; };
00183 };
00184
00185 template <int lenwidth>
00186 class VariableWidthValue : public FieldValue::Data {
00187 std::vector<uint8_t> octets;
00188
00189 public:
00190 VariableWidthValue() {}
00191 VariableWidthValue(const std::vector<uint8_t>& data) : octets(data) {}
00192 VariableWidthValue(const uint8_t* start, const uint8_t* end) : octets(start, end) {}
00193 uint32_t encodedSize() const { return lenwidth + octets.size(); }
00194 void encode(Buffer& buffer) {
00195 buffer.putUInt<lenwidth>(octets.size());
00196 if (octets.size() > 0)
00197 buffer.putRawData(&octets[0], octets.size());
00198 };
00199 void decode(Buffer& buffer) {
00200 uint32_t len = buffer.getUInt<lenwidth>();
00201 octets.resize(len);
00202 if (len > 0)
00203 buffer.getRawData(&octets[0], len);
00204 }
00205 bool operator==(const Data& d) const {
00206 const VariableWidthValue<lenwidth>* rhs = dynamic_cast< const VariableWidthValue<lenwidth>* >(&d);
00207 if (rhs == 0) return false;
00208 else return octets==rhs->octets;
00209 }
00210
00211 bool convertsToString() const { return true; }
00212 std::string getString() const { return std::string(octets.begin(), octets.end()); }
00213
00214 void print(std::ostream& o) const { o << "V" << lenwidth << ":" << octets.size() << ":"; };
00215 };
00216
00217 template <class T>
00218 class EncodedValue : public FieldValue::Data {
00219 T value;
00220 public:
00221
00222 EncodedValue() {}
00223 EncodedValue(const T& v) : value(v) {}
00224
00225 T& getValue() { return value; }
00226 const T& getValue() const { return value; }
00227
00228 uint32_t encodedSize() const { return value.encodedSize(); }
00229
00230 void encode(Buffer& buffer) {
00231 value.encode(buffer);
00232 };
00233 void decode(Buffer& buffer) {
00234 value.decode(buffer);
00235 }
00236 bool operator==(const Data& d) const {
00237 const EncodedValue<T>* rhs = dynamic_cast< const EncodedValue<T>* >(&d);
00238 if (rhs == 0) return false;
00239 else return value==rhs->value;
00240 }
00241
00242 void print(std::ostream& o) const { o << "[" << value << "]"; };
00243 };
00244
00245 class Str8Value : public FieldValue {
00246 public:
00247 Str8Value(const std::string& v);
00248 };
00249
00250 class Str16Value : public FieldValue {
00251 public:
00252 Str16Value(const std::string& v);
00253 };
00254
00255 class Struct32Value : public FieldValue {
00256 public:
00257 Struct32Value(const std::string& v);
00258 };
00259
00260 class FloatValue : public FieldValue
00261 {
00262 public:
00263 FloatValue(float f);
00264 };
00265 class DoubleValue : public FieldValue
00266 {
00267 public:
00268 DoubleValue(double f);
00269 };
00270
00271
00272
00273
00274 class IntegerValue : public FieldValue {
00275 public:
00276 IntegerValue(int v);
00277 };
00278
00279 class TimeValue : public FieldValue {
00280 public:
00281 TimeValue(uint64_t v);
00282 };
00283
00284 class Integer64Value : public FieldValue {
00285 public:
00286 Integer64Value(int64_t v);
00287 };
00288
00289 class Unsigned64Value : public FieldValue {
00290 public:
00291 Unsigned64Value(uint64_t v);
00292 };
00293
00294 class FieldTableValue : public FieldValue {
00295 public:
00296 FieldTableValue(const FieldTable&);
00297 };
00298
00299 class ArrayValue : public FieldValue {
00300 public:
00301 ArrayValue(const Array&);
00302 };
00303
00304 template <class T>
00305 bool getEncodedValue(FieldTable::ValuePtr vptr, T& value)
00306 {
00307 if (vptr) {
00308 const EncodedValue<T>* ev = dynamic_cast< EncodedValue<T>* >(&(vptr->getData()));
00309 if (ev != 0) {
00310 value = ev->getValue();
00311 return true;
00312 }
00313 }
00314 return false;
00315 }
00316
00317
00318 }}
00319
00320 #endif