From 52be8c6219f98781d83711b32d4c5971b1fa6d1c Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Thu, 11 Jun 2009 15:54:37 +0000 Subject: QPID-1786 - Committed qmf patches from Bryan Kearney Additionally updated existing qmf and Qman to be compatible. The magic number for qmf messages has been incremented. git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@783818 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/src/qpid/framing/FieldTable.cpp | 135 +++++++++++++++++++++++++++++++++++- 1 file changed, 134 insertions(+), 1 deletion(-) (limited to 'cpp/src/qpid/framing/FieldTable.cpp') diff --git a/cpp/src/qpid/framing/FieldTable.cpp b/cpp/src/qpid/framing/FieldTable.cpp index 559aa8b013..3e0921fe8d 100644 --- a/cpp/src/qpid/framing/FieldTable.cpp +++ b/cpp/src/qpid/framing/FieldTable.cpp @@ -53,6 +53,23 @@ uint32_t FieldTable::encodedSize() const { return len; } +uint32_t FieldTable::qmfEncodedSize() const { + uint32_t len(4/*size field*/ + 4/*count field*/); + for(ValueMap::const_iterator i = values.begin(); i != values.end(); ++i) { + // shortstr_len_byte + key size + typecode + len += 1 + (i->first).size() + 1; + ValuePtr value(i->second); + if (value->convertsTo()) { + len += 4; + } else if (value->convertsTo()) { + len += 8; + } else if (value->convertsTo()) { + len += 2 + value->get().size(); + } + } + return len; +} + int FieldTable::count() const { return values.size(); } @@ -191,7 +208,7 @@ bool FieldTable::getDouble(const std::string& name, double& value) const { // return getValue(name); //} -void FieldTable::encode(Buffer& buffer) const{ +void FieldTable::encode(Buffer& buffer) const { buffer.putLong(encodedSize() - 4); buffer.putLong(values.size()); for (ValueMap::const_iterator i = values.begin(); i!=values.end(); ++i) { @@ -220,6 +237,122 @@ void FieldTable::decode(Buffer& buffer){ } } +#define QMF_TYPE_U8 1 +#define QMF_TYPE_U16 2 +#define QMF_TYPE_U32 3 +#define QMF_TYPE_U64 4 +#define QMF_TYPE_SSTR 6 +#define QMF_TYPE_LSTR 7 +#define QMF_TYPE_ABSTIME 8 +#define QMF_TYPE_DELTATIME 9 +#define QMF_TYPE_REF 10 +#define QMF_TYPE_BOOL 11 +#define QMF_TYPE_FLOAT 12 +#define QMF_TYPE_DOUBLE 13 +#define QMF_TYPE_UUID 14 +#define QMF_TYPE_S8 16 +#define QMF_TYPE_S16 17 +#define QMF_TYPE_S32 18 +#define QMF_TYPE_S64 19 +#define QMF_TYPE_OBJECT 20 +#define QMF_TYPE_MAP 15 +#define QMF_TYPE_LIST 21 +#define QMF_TYPE_ARRAY 22 + +void FieldTable::qmfEncode(Buffer& buffer) const { + buffer.putLong(qmfEncodedSize() - 4); + buffer.putLong(values.size()); + for (ValueMap::const_iterator i = values.begin(); i!=values.end(); ++i) { + ValuePtr value(i->second); + buffer.putShortString(i->first); + if (value->convertsTo()) { + buffer.putOctet(QMF_TYPE_S32); + buffer.putLong(value->get()); + } else if (value->convertsTo()) { + buffer.putOctet(QMF_TYPE_U64); + buffer.putLongLong(value->get()); + } else if (value->convertsTo()) { + buffer.putOctet(QMF_TYPE_LSTR); + buffer.putMediumString(value->get()); + } + } +} + +void FieldTable::qmfDecode(Buffer& buffer) { + clear(); + uint32_t len = buffer.getLong(); + if (len) { + uint32_t available = buffer.available(); + if (available < len) + throw IllegalArgumentException(QPID_MSG("Not enough data for field table.")); + uint32_t count = buffer.getLong(); + uint32_t leftover = available - len; + while(buffer.available() > leftover && count--) { + std::string name; + std::string sstr; + std::string lstr; + buffer.getShortString(name); + uint8_t typecode = buffer.getOctet(); + switch (typecode) { + case QMF_TYPE_U8: + values[name] = ValuePtr(new IntegerValue(buffer.getOctet())); + break; + case QMF_TYPE_U16: + values[name] = ValuePtr(new IntegerValue(buffer.getShort())); + break; + case QMF_TYPE_U32: + values[name] = ValuePtr(new IntegerValue(buffer.getLong())); + break; + case QMF_TYPE_U64: + values[name] = ValuePtr(new Unsigned64Value(buffer.getLongLong())); + break; + case QMF_TYPE_SSTR: + buffer.getShortString(sstr); + values[name] = ValuePtr(new Str16Value(sstr)); + break; + case QMF_TYPE_LSTR: + buffer.getMediumString(lstr); + values[name] = ValuePtr(new Str16Value(lstr)); + break; + case QMF_TYPE_ABSTIME: + values[name] = ValuePtr(new Unsigned64Value(buffer.getLongLong())); + break; + case QMF_TYPE_DELTATIME: + values[name] = ValuePtr(new Unsigned64Value(buffer.getLongLong())); + break; + case QMF_TYPE_BOOL: + values[name] = ValuePtr(new IntegerValue(buffer.getOctet())); + break; + case QMF_TYPE_FLOAT: + values[name] = ValuePtr(new FloatValue(buffer.getFloat())); + break; + case QMF_TYPE_DOUBLE: + values[name] = ValuePtr(new DoubleValue(buffer.getDouble())); + break; + case QMF_TYPE_S8: + values[name] = ValuePtr(new IntegerValue(buffer.getOctet())); + break; + case QMF_TYPE_S16: + values[name] = ValuePtr(new IntegerValue(buffer.getShort())); + break; + case QMF_TYPE_S32: + values[name] = ValuePtr(new IntegerValue(buffer.getLong())); + break; + case QMF_TYPE_S64: + values[name] = ValuePtr(new Unsigned64Value(buffer.getLongLong())); + break; + case QMF_TYPE_REF: + case QMF_TYPE_UUID: + case QMF_TYPE_OBJECT: + case QMF_TYPE_MAP: + case QMF_TYPE_LIST: + case QMF_TYPE_ARRAY: + break; + } + } + } +} + bool FieldTable::operator==(const FieldTable& x) const { if (values.size() != x.values.size()) return false; -- cgit v1.2.1