From 26473ff13bc938af2893200fea7e62e3d79d173f Mon Sep 17 00:00:00 2001 From: Alan Conway Date: Thu, 10 Apr 2008 20:15:08 +0000 Subject: amqp_0_10: Encoding for packed structs. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@646943 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/src/qpid/amqp_0_10/Packer.h | 30 +++++++++++++++++++++++------- cpp/src/qpid/amqp_0_10/built_in_types.h | 15 +++++++++------ cpp/src/qpid/amqp_0_10/complex_types.cpp | 19 +++++++------------ cpp/src/qpid/amqp_0_10/complex_types.h | 1 + 4 files changed, 40 insertions(+), 25 deletions(-) (limited to 'cpp/src/qpid') diff --git a/cpp/src/qpid/amqp_0_10/Packer.h b/cpp/src/qpid/amqp_0_10/Packer.h index 8943dc4c51..90d72408b5 100644 --- a/cpp/src/qpid/amqp_0_10/Packer.h +++ b/cpp/src/qpid/amqp_0_10/Packer.h @@ -24,6 +24,7 @@ #include #include +#include "qpid/amqp_0_10/built_in_types.h" namespace qpid { namespace amqp_0_10 { @@ -60,17 +61,21 @@ class PackBits { public: PackBits() : bit(1), bits(0) {} - void setBit() { bits |= bit; bit <<= 1; } - void skipBit() { bit <<= 1; } - + void setBit(bool b) { if (b) bits |= bit; bit <<= 1; } uint32_t getBits() { return bits; } - - template PackBits& operator()(const T&) { setBit(); return *this; } + /** The bit is always set for non-optional values. */ + template + PackBits& operator()(const T&) { setBit(1); return *this; } + + /** For optional values the bit is set if the value is present. */ template PackBits& operator()(const boost::optional& opt) { - opt ? setBit() : skipBit(); return *this; + setBit(opt); return *this; } + /** Bits are special optional values */ + PackBits& operator()(Bit b) { setBit(b); return *this; } + private: uint32_t bit; uint32_t bits; @@ -83,12 +88,23 @@ template uint32_t packBits(const T& t) { return pack.getBits(); } +/** Decode members enabled by Bits */ template class PackedDecoder { public: PackedDecoder(Decoder& d, Bits b) : decode(d), bits(b) {} - template PackedDecoder& operator()(T& t) { decode(t); return *this; } + template PackedDecoder& operator()(T& t) { + if (bits & 1) + decode(t); + else + t = T(); + // FIXME aconway 2008-04-10: When we have all optionals + // represented by boost::optional the line above should be: + // throw CommandInvalidException("A required value was omitted."); + bits >>= 1; + return *this; + } template PackedDecoder& operator()(boost::optional& opt) { if (bits & 1) { diff --git a/cpp/src/qpid/amqp_0_10/built_in_types.h b/cpp/src/qpid/amqp_0_10/built_in_types.h index 5b79faef36..dccb6a4785 100644 --- a/cpp/src/qpid/amqp_0_10/built_in_types.h +++ b/cpp/src/qpid/amqp_0_10/built_in_types.h @@ -61,14 +61,17 @@ inline std::ostream& operator<<(std::ostream& o, const Wrapper& w) { struct Void { template void serialize(S&) {} }; inline std::ostream& operator<<(std::ostream& o, const Void&) { return o; } -/** Bit type - bool value with no encoding. */ -struct Bit : Wrapper { - template void serialize(S& s) { s.split(*this); } - template void encode(S&) const {} - template void decode(S&) { value=true; } +/** Bit is a presence indicator - an optional value with no encoding. */ +struct Bit : public Wrapper { + Bit(bool b=false) : Wrapper(b) {} + using Wrapper::operator=; + template void serialize(S& s) { s.split(*this); } + template void encode(S&) const { } + template void decode(S&) { *this = true; } }; + inline std::ostream& operator<<(std::ostream& o, const Bit& b) { - return o << b.value; + return o << bool(b); } // Fixed size types diff --git a/cpp/src/qpid/amqp_0_10/complex_types.cpp b/cpp/src/qpid/amqp_0_10/complex_types.cpp index 93550b9c20..78ddfeb026 100644 --- a/cpp/src/qpid/amqp_0_10/complex_types.cpp +++ b/cpp/src/qpid/amqp_0_10/complex_types.cpp @@ -21,7 +21,7 @@ #include "qpid/amqp_0_10/ApplyCommand.h" #include "qpid/amqp_0_10/ApplyControl.h" -// FIXME aconway 2008-03-04: #include "qpid/amqp_0_10/ApplyStruct.h" +#include "qpid/amqp_0_10/ApplyStruct.h" #include "qpid/amqp_0_10/apply.h" #include @@ -52,15 +52,11 @@ uint8_t Control::getClassCode() const { return apply(GetClassCode(), *this); } const char* Control::getName() const { return apply(GetName(), *this); } const char* Control::getClassName() const { return apply(GetClassName(), *this); } -// FIXME aconway 2008-03-04: Struct visitors -// uint8_t Struct::getCode() const { return apply(GetCode(), *this); } -// uint8_t Struct::getPack() const { return apply(GetPack(), *this); } -// uint8_t Struct::getSize() const { return apply(GetSize(), *this); } -// uint8_t Struct::getClassCode() const { return apply(GetClassCode(), *this); } -uint8_t Struct::getCode() const { assert(0); return 0; } -uint8_t Struct::getPack() const { assert(0); return 0; } -uint8_t Struct::getSize() const { assert(0); return 0; } -uint8_t Struct::getClassCode() const { assert(0); return 0; } + +uint8_t Struct::getCode() const { return apply(GetCode(), *this); } +uint8_t Struct::getPack() const { return apply(GetPack(), *this); } +uint8_t Struct::getSize() const { return apply(GetSize(), *this); } +uint8_t Struct::getClassCode() const { return apply(GetClassCode(), *this); } struct PrintVisitor { typedef std::ostream& result_type; @@ -71,8 +67,7 @@ struct PrintVisitor { std::ostream& operator<<(std::ostream& o, const Command& x) { return apply(PrintVisitor(o), x); } std::ostream& operator<<(std::ostream& o, const Control& x) { return apply(PrintVisitor(o), x); } -// FIXME aconway 2008-04-07: -// std::ostream& operator<<(std::ostream& o, const Struct& x) { apply(PrintVisitor(o), x); } +std::ostream& operator<<(std::ostream& o, const Struct& x) { return apply(PrintVisitor(o), x); } }} // namespace qpid::amqp_0_10 diff --git a/cpp/src/qpid/amqp_0_10/complex_types.h b/cpp/src/qpid/amqp_0_10/complex_types.h index c8080b867d..5d327cc46e 100644 --- a/cpp/src/qpid/amqp_0_10/complex_types.h +++ b/cpp/src/qpid/amqp_0_10/complex_types.h @@ -90,6 +90,7 @@ struct Control }; std::ostream& operator<<(std::ostream&, const Control&); +// Note: only coded structs inherit from Struct. struct StructVisitor; struct ConstStructVisitor; struct StructHolder; -- cgit v1.2.1