From b7628599ca9fa276bc9fc072804f44cd3d4765ea Mon Sep 17 00:00:00 2001 From: Gordon Sim Date: Thu, 20 Aug 2009 13:25:06 +0000 Subject: Add List class to handle encoding of AMQP 0-10 list type. Fill out accessors for different FieldValue types. git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@806162 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/include/qpid/framing/FieldTable.h | 8 ++- cpp/include/qpid/framing/FieldValue.h | 117 +++++++++++++++++++++++++++++++++- cpp/include/qpid/framing/List.h | 76 ++++++++++++++++++++++ 3 files changed, 198 insertions(+), 3 deletions(-) create mode 100644 cpp/include/qpid/framing/List.h (limited to 'cpp/include') diff --git a/cpp/include/qpid/framing/FieldTable.h b/cpp/include/qpid/framing/FieldTable.h index a3a5c8a4ee..b2331cd4e1 100644 --- a/cpp/include/qpid/framing/FieldTable.h +++ b/cpp/include/qpid/framing/FieldTable.h @@ -51,6 +51,8 @@ class FieldTable typedef boost::shared_ptr ValuePtr; typedef std::map ValueMap; typedef ValueMap::iterator iterator; + typedef ValueMap::const_reference const_reference; + typedef ValueMap::value_type value_type; QPID_COMMON_EXTERN FieldTable() {}; QPID_COMMON_EXTERN FieldTable(const FieldTable& ft); @@ -97,12 +99,16 @@ class FieldTable QPID_COMMON_EXTERN bool operator==(const FieldTable& other) const; // Map-like interface. - // TODO: may need to duplicate into versions that return mutable iterator ValueMap::const_iterator begin() const { return values.begin(); } ValueMap::const_iterator end() const { return values.end(); } ValueMap::const_iterator find(const std::string& s) const { return values.find(s); } + ValueMap::iterator begin() { return values.begin(); } + ValueMap::iterator end() { return values.end(); } + ValueMap::iterator find(const std::string& s) { return values.find(s); } + std::pair insert(const ValueMap::value_type&); + ValueMap::iterator insert(ValueMap::iterator, const ValueMap::value_type&); void clear() { values.clear(); } // ### Hack Alert diff --git a/cpp/include/qpid/framing/FieldValue.h b/cpp/include/qpid/framing/FieldValue.h index 97fc56d606..6c2f5b5876 100644 --- a/cpp/include/qpid/framing/FieldValue.h +++ b/cpp/include/qpid/framing/FieldValue.h @@ -24,6 +24,7 @@ #include "qpid/Exception.h" #include "qpid/framing/amqp_types.h" #include "qpid/framing/Buffer.h" +#include "qpid/framing/Endian.h" #include "qpid/framing/FieldTable.h" #include "qpid/CommonImportExport.h" @@ -36,7 +37,6 @@ namespace qpid { namespace framing { -//class Array; /** * Exception that is the base exception for all field table errors. * @@ -53,6 +53,8 @@ struct InvalidConversionException : public FieldValueException { InvalidConversionException() {} }; +class List; + /** * Value that can appear in an AMQP field table * @@ -96,12 +98,17 @@ class FieldValue { template bool convertsTo() const { return false; } template T get() const { throw InvalidConversionException(); } + template T getIntegerValue() const; + template T getFloatingPointValue() const; + template bool get(T&) const; + protected: FieldValue(uint8_t t, Data* d): typeOctet(t), data(d) {} private: uint8_t typeOctet; std::auto_ptr data; + }; template <> @@ -165,10 +172,52 @@ class FixedWidthValue : public FieldValue::Data { return v; } uint8_t* rawOctets() { return octets; } + uint8_t* rawOctets() const { return octets; } void print(std::ostream& o) const { o << "F" << width << ":"; }; }; +template +inline T FieldValue::getIntegerValue() const +{ + FixedWidthValue* const fwv = dynamic_cast< FixedWidthValue* const>(data.get()); + if (fwv) { + uint8_t* octets = fwv->rawOctets(); + T v = 0; + for (int i = 0; i < W-1; ++i) { + v |= octets[i]; v <<= 8; + } + v |= octets[W-1]; + return v; + } else { + throw InvalidConversionException(); + } +} + +template +inline T FieldValue::getFloatingPointValue() const { + FixedWidthValue* const fwv = dynamic_cast< FixedWidthValue* const>(data.get()); + if (fwv) { + T value; + uint8_t* const octets = Endian::convertIfRequired(fwv->rawOctets(), W); + uint8_t* const target = reinterpret_cast(&value); + for (uint i = 0; i < W; ++i) target[i] = octets[i]; + return value; + } else { + throw InvalidConversionException(); + } +} + +template <> +inline float FieldValue::get() const { + return getFloatingPointValue(); +} + +template <> +inline double FieldValue::get() const { + return getFloatingPointValue(); +} + template <> class FixedWidthValue<0> : public FieldValue::Data { public: @@ -243,6 +292,27 @@ class EncodedValue : public FieldValue::Data { void print(std::ostream& o) const { o << "[" << value << "]"; }; }; +/** + * Accessor that can be used to get values of type FieldTable, Array + * and List. + */ +template +inline bool FieldValue::get(T& t) const +{ + const EncodedValue* v = dynamic_cast< EncodedValue* >(data.get()); + if (v != 0) { + t = v->getValue(); + return true; + } else { + try { + t = get(); + return true; + } catch (const InvalidConversionException&) { + return false; + } + } +} + class Str8Value : public FieldValue { public: QPID_COMMON_EXTERN Str8Value(const std::string& v); @@ -294,6 +364,7 @@ class Unsigned64Value : public FieldValue { class FieldTableValue : public FieldValue { public: + typedef FieldTable ValueType; QPID_COMMON_EXTERN FieldTableValue(const FieldTable&); }; @@ -302,6 +373,49 @@ class ArrayValue : public FieldValue { QPID_COMMON_EXTERN ArrayValue(const Array&); }; +class VoidValue : public FieldValue { + public: + QPID_COMMON_EXTERN VoidValue(); +}; + +class BoolValue : public FieldValue { + public: + QPID_COMMON_EXTERN BoolValue(bool); +}; + +class Unsigned8Value : public FieldValue { + public: + QPID_COMMON_EXTERN Unsigned8Value(uint8_t); +}; + +class Unsigned16Value : public FieldValue { + public: + QPID_COMMON_EXTERN Unsigned16Value(uint16_t); +}; + +class Unsigned32Value : public FieldValue { + public: + QPID_COMMON_EXTERN Unsigned32Value(uint32_t); +}; + +class Integer8Value : public FieldValue { + public: + QPID_COMMON_EXTERN Integer8Value(int8_t); +}; + +class Integer16Value : public FieldValue { + public: + QPID_COMMON_EXTERN Integer16Value(int16_t); +}; + +typedef IntegerValue Integer32Value; + +class ListValue : public FieldValue { + public: + typedef List ValueType; + QPID_COMMON_EXTERN ListValue(const List&); +}; + template bool getEncodedValue(FieldTable::ValuePtr vptr, T& value) { @@ -315,7 +429,6 @@ bool getEncodedValue(FieldTable::ValuePtr vptr, T& value) return false; } - }} // qpid::framing #endif diff --git a/cpp/include/qpid/framing/List.h b/cpp/include/qpid/framing/List.h new file mode 100644 index 0000000000..cb1129ebf8 --- /dev/null +++ b/cpp/include/qpid/framing/List.h @@ -0,0 +1,76 @@ +#ifndef QPID_FRAMING_LIST_H +#define QPID_FRAMING_LIST_H + +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +#include "qpid/CommonImportExport.h" +#include "qpid/framing/amqp_types.h" +#include +#include +#include + +namespace qpid { +namespace framing { + +class Buffer; +class FieldValue; + +/** + * Representation of an AMQP 0-10 list + */ +class List +{ + public: + typedef boost::shared_ptr ValuePtr; + typedef std::list Values; + typedef Values::const_iterator const_iterator; + typedef Values::iterator iterator; + typedef Values::const_reference const_reference; + + QPID_COMMON_EXTERN uint32_t encodedSize() const; + QPID_COMMON_EXTERN void encode(Buffer& buffer) const; + QPID_COMMON_EXTERN void decode(Buffer& buffer); + + QPID_COMMON_EXTERN bool operator==(const List& other) const; + + // std collection interface. + QPID_COMMON_EXTERN const_iterator begin() const { return values.begin(); } + QPID_COMMON_EXTERN const_iterator end() const { return values.end(); } + QPID_COMMON_EXTERN iterator begin() { return values.begin(); } + QPID_COMMON_EXTERN iterator end(){ return values.end(); } + + QPID_COMMON_EXTERN ValuePtr front() const { return values.front(); } + QPID_COMMON_EXTERN ValuePtr back() const { return values.back(); } + QPID_COMMON_EXTERN size_t size() const { return values.size(); } + + QPID_COMMON_EXTERN iterator insert(iterator i, ValuePtr value) { return values.insert(i, value); } + QPID_COMMON_EXTERN void erase(iterator i) { values.erase(i); } + QPID_COMMON_EXTERN void push_back(ValuePtr value) { values.insert(end(), value); } + QPID_COMMON_EXTERN void pop_back() { values.pop_back(); } + + private: + Values values; + + friend QPID_COMMON_EXTERN std::ostream& operator<<(std::ostream& out, const List& list); +}; +}} // namespace qpid::framing + +#endif /*!QPID_FRAMING_LIST_H*/ -- cgit v1.2.1