summaryrefslogtreecommitdiff
path: root/qpid/cpp
diff options
context:
space:
mode:
authorGordon Sim <gsim@apache.org>2008-09-19 12:56:38 +0000
committerGordon Sim <gsim@apache.org>2008-09-19 12:56:38 +0000
commit67de58e3a19c5fe39bb59de80425ee9f94271bfa (patch)
tree98c359878e54d97152db7cfea0771b67f0270679 /qpid/cpp
parenta479c8cd6985db06f9c9bf372587824da4ccb11a (diff)
downloadqpid-python-67de58e3a19c5fe39bb59de80425ee9f94271bfa.tar.gz
Added support for nested field tables & arrays within a field table.
git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@697076 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/cpp')
-rw-r--r--qpid/cpp/src/qpid/framing/FieldTable.cpp29
-rw-r--r--qpid/cpp/src/qpid/framing/FieldTable.h5
-rw-r--r--qpid/cpp/src/qpid/framing/FieldValue.cpp106
-rw-r--r--qpid/cpp/src/qpid/framing/FieldValue.h45
-rw-r--r--qpid/cpp/src/tests/FieldTable.cpp40
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()