diff options
Diffstat (limited to 'qpid/cpp')
-rw-r--r-- | qpid/cpp/src/qpid/framing/FieldTable.cpp | 29 | ||||
-rw-r--r-- | qpid/cpp/src/qpid/framing/FieldTable.h | 5 | ||||
-rw-r--r-- | qpid/cpp/src/qpid/framing/FieldValue.cpp | 106 | ||||
-rw-r--r-- | qpid/cpp/src/qpid/framing/FieldValue.h | 45 | ||||
-rw-r--r-- | qpid/cpp/src/tests/FieldTable.cpp | 40 |
5 files changed, 170 insertions, 55 deletions
diff --git a/qpid/cpp/src/qpid/framing/FieldTable.cpp b/qpid/cpp/src/qpid/framing/FieldTable.cpp index bd20c10c37..5a5d755fe8 100644 --- a/qpid/cpp/src/qpid/framing/FieldTable.cpp +++ b/qpid/cpp/src/qpid/framing/FieldTable.cpp @@ -19,6 +19,7 @@ * */ #include "FieldTable.h" +#include "Array.h" #include "Buffer.h" #include "FieldValue.h" #include "qpid/Exception.h" @@ -77,9 +78,14 @@ void FieldTable::setTimestamp(const std::string& name, uint64_t value){ values[name] = ValuePtr(new TimeValue(value)); } -void FieldTable::setTable(const std::string& name, const FieldTable& value){ +void FieldTable::setTable(const std::string& name, const FieldTable& value) +{ values[name] = ValuePtr(new FieldTableValue(value)); } +void FieldTable::setArray(const std::string& name, const Array& value) +{ + values[name] = ValuePtr(new ArrayValue(value)); +} FieldTable::ValuePtr FieldTable::get(const std::string& name) const { @@ -116,10 +122,23 @@ int FieldTable::getInt(const std::string& name) const { //uint64_t FieldTable::getTimestamp(const std::string& name) const { // return getValue<uint64_t>(name); //} -// -//void FieldTable::getTable(const std::string& name, FieldTable& value) const { -// value = getValue<FieldTable>(name); -//} + +void FieldTable::getTable(const std::string& name, FieldTable& value) const { + FieldTable::ValuePtr vptr = get(name); + if (vptr) { + value = vptr->get<const FieldTable&>(); + } +} + +void FieldTable::getArray(const std::string& name, Array& value) const { + FieldTable::ValuePtr vptr = get(name); + if (vptr) { + const EncodedValue<Array>* ev = dynamic_cast< EncodedValue<Array>* >(&(vptr->getData())); + if (ev != 0) { + value = ev->getValue(); + } + } +} void FieldTable::encode(Buffer& buffer) const{ buffer.putLong(size() - 4); diff --git a/qpid/cpp/src/qpid/framing/FieldTable.h b/qpid/cpp/src/qpid/framing/FieldTable.h index ed27f3fef6..4a0d4da11e 100644 --- a/qpid/cpp/src/qpid/framing/FieldTable.h +++ b/qpid/cpp/src/qpid/framing/FieldTable.h @@ -34,6 +34,7 @@ namespace qpid { */ namespace framing { +class Array; class FieldValue; class Buffer; @@ -64,12 +65,14 @@ class FieldTable void setInt(const std::string& name, int value); void setTimestamp(const std::string& name, uint64_t value); void setTable(const std::string& name, const FieldTable& value); + void setArray(const std::string& name, const Array& value); //void setDecimal(string& name, xxx& value); std::string getString(const std::string& name) const; int getInt(const std::string& name) const; // uint64_t getTimestamp(const std::string& name) const; -// void getTable(const std::string& name, FieldTable& value) const; + void getTable(const std::string& name, FieldTable& value) const; + void getArray(const std::string& name, Array& value) const; // //void getDecimal(string& name, xxx& value); // //void erase(const std::string& name); diff --git a/qpid/cpp/src/qpid/framing/FieldValue.cpp b/qpid/cpp/src/qpid/framing/FieldValue.cpp index 681f20a793..3b3c2f2126 100644 --- a/qpid/cpp/src/qpid/framing/FieldValue.cpp +++ b/qpid/cpp/src/qpid/framing/FieldValue.cpp @@ -19,6 +19,7 @@ * */ #include "FieldValue.h" +#include "Array.h" #include "Buffer.h" #include "qpid/framing/reply_exceptions.h" @@ -33,53 +34,58 @@ uint8_t FieldValue::getType() void FieldValue::setType(uint8_t type) { typeOctet = type; - - uint8_t lenType = typeOctet >> 4; - switch(lenType){ - case 0: - data.reset(new FixedWidthValue<1>()); - break; - case 1: - data.reset(new FixedWidthValue<2>()); - break; - case 2: - data.reset(new FixedWidthValue<4>()); - break; - case 3: - data.reset(new FixedWidthValue<8>()); - break; - case 4: - data.reset(new FixedWidthValue<16>()); - break; - case 5: - data.reset(new FixedWidthValue<32>()); - break; - case 6: - data.reset(new FixedWidthValue<64>()); - break; - case 7: - data.reset(new FixedWidthValue<128>()); - break; - case 8: - data.reset(new VariableWidthValue<1>()); - break; - case 9: - data.reset(new VariableWidthValue<2>()); - break; - case 0xA: - data.reset(new VariableWidthValue<4>()); - break; - case 0xC: - data.reset(new FixedWidthValue<5>()); - break; - case 0xD: - data.reset(new FixedWidthValue<9>()); - break; - case 0xF: - data.reset(new FixedWidthValue<0>()); - break; - default: - throw IllegalArgumentException(QPID_MSG("Unknown field table value type: " << (int)typeOctet)); + if (typeOctet == 0xA8) { + data.reset(new EncodedValue<FieldTable>()); + } else if (typeOctet == 0xAA) { + data.reset(new EncodedValue<Array>()); + } else { + uint8_t lenType = typeOctet >> 4; + switch(lenType){ + case 0: + data.reset(new FixedWidthValue<1>()); + break; + case 1: + data.reset(new FixedWidthValue<2>()); + break; + case 2: + data.reset(new FixedWidthValue<4>()); + break; + case 3: + data.reset(new FixedWidthValue<8>()); + break; + case 4: + data.reset(new FixedWidthValue<16>()); + break; + case 5: + data.reset(new FixedWidthValue<32>()); + break; + case 6: + data.reset(new FixedWidthValue<64>()); + break; + case 7: + data.reset(new FixedWidthValue<128>()); + break; + case 8: + data.reset(new VariableWidthValue<1>()); + break; + case 9: + data.reset(new VariableWidthValue<2>()); + break; + case 0xA: + data.reset(new VariableWidthValue<4>()); + break; + case 0xC: + data.reset(new FixedWidthValue<5>()); + break; + case 0xD: + data.reset(new FixedWidthValue<9>()); + break; + case 0xF: + data.reset(new FixedWidthValue<0>()); + break; + default: + throw IllegalArgumentException(QPID_MSG("Unknown field table value type: " << (int)typeOctet)); + } } } @@ -137,7 +143,11 @@ TimeValue::TimeValue(uint64_t v) : { } -FieldTableValue::FieldTableValue(const FieldTable&) : FieldValue() +FieldTableValue::FieldTableValue(const FieldTable& f) : FieldValue(0xa8, new EncodedValue<FieldTable>(f)) +{ +} + +ArrayValue::ArrayValue(const Array& a) : FieldValue(0xaa, new EncodedValue<Array>(a)) { } diff --git a/qpid/cpp/src/qpid/framing/FieldValue.h b/qpid/cpp/src/qpid/framing/FieldValue.h index a4c20bf415..a19375fcef 100644 --- a/qpid/cpp/src/qpid/framing/FieldValue.h +++ b/qpid/cpp/src/qpid/framing/FieldValue.h @@ -22,8 +22,9 @@ */ #include "qpid/Exception.h" -#include "Buffer.h" #include "amqp_types.h" +#include "Buffer.h" +#include "FieldTable.h" #include "assert.h" @@ -34,6 +35,7 @@ namespace qpid { namespace framing { +//class Array; /** * Exception that is the base exception for all field table errors. * @@ -199,6 +201,42 @@ class VariableWidthValue : public FieldValue::Data { void print(std::ostream& o) const { o << "V" << lenwidth << ":" << octets.size() << ":"; }; }; +template <class T> +class EncodedValue : public FieldValue::Data { + T value; + public: + + EncodedValue() {} + EncodedValue(const T& v) : value(v) {} + + T& getValue() { return value; } + const T& getValue() const { return value; } + + uint32_t size() const { return value.size(); } + + void encode(Buffer& buffer) { + value.encode(buffer); + }; + void decode(Buffer& buffer) { + value.decode(buffer); + } + bool operator==(const Data& d) const { + const EncodedValue<T>* rhs = dynamic_cast< const EncodedValue<T>* >(&d); + if (rhs == 0) return false; + else return value==rhs->value; + } + + void print(std::ostream& o) const { o << "[" << value << "]"; }; +}; + +template <> +inline const FieldTable& FieldValue::get<const FieldTable&>() const +{ + const EncodedValue<FieldTable>* ev = dynamic_cast< EncodedValue<FieldTable>* >(data.get()); + if (ev == 0) throw InvalidConversionException(); + return ev->getValue(); +} + /* * Basic string value encodes as iso-8859-15 with 32 bit length */ @@ -236,6 +274,11 @@ class FieldTableValue : public FieldValue { FieldTableValue(const FieldTable&); }; +class ArrayValue : public FieldValue { + public: + ArrayValue(const Array&); +}; + }} // qpid::framing #endif diff --git a/qpid/cpp/src/tests/FieldTable.cpp b/qpid/cpp/src/tests/FieldTable.cpp index 315801b428..22db287140 100644 --- a/qpid/cpp/src/tests/FieldTable.cpp +++ b/qpid/cpp/src/tests/FieldTable.cpp @@ -19,6 +19,7 @@ * */ #include <iostream> +#include "qpid/framing/Array.h" #include "qpid/framing/FieldTable.h" #include "qpid/framing/FieldValue.h" #include <alloca.h> @@ -82,4 +83,43 @@ QPID_AUTO_TEST_CASE(testAssignment) BOOST_CHECK(IntegerValue(1234) == *d.get("B")); } + +QPID_AUTO_TEST_CASE(testNestedValues) +{ + char buff[100]; + { + FieldTable a; + FieldTable b; + std::vector<std::string> items; + items.push_back("one"); + items.push_back("two"); + Array c(items); + + a.setString("id", "A"); + b.setString("id", "B"); + a.setTable("B", b); + a.setArray("C", c); + + + Buffer wbuffer(buff, 100); + wbuffer.put(a); + } + { + Buffer rbuffer(buff, 100); + FieldTable a; + FieldTable b; + Array c; + rbuffer.get(a); + BOOST_CHECK(string("A") == a.getString("id")); + a.getTable("B", b); + BOOST_CHECK(string("B") == b.getString("id")); + a.getArray("C", c); + std::vector<std::string> items; + c.collect(items); + BOOST_CHECK((uint) 2 == items.size()); + BOOST_CHECK(string("one") == items[0]); + BOOST_CHECK(string("two") == items[1]); + } +} + QPID_AUTO_TEST_SUITE_END() |