summaryrefslogtreecommitdiff
path: root/cpp/src/qpid
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src/qpid')
-rw-r--r--cpp/src/qpid/amqp_0_10/Packer.h30
-rw-r--r--cpp/src/qpid/amqp_0_10/built_in_types.h15
-rw-r--r--cpp/src/qpid/amqp_0_10/complex_types.cpp19
-rw-r--r--cpp/src/qpid/amqp_0_10/complex_types.h1
4 files changed, 40 insertions, 25 deletions
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 <boost/optional.hpp>
#include <boost/none.hpp>
+#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 <class T> PackBits& operator()(const T&) { setBit(); return *this; }
+ /** The bit is always set for non-optional values. */
+ template <class T>
+ PackBits& operator()(const T&) { setBit(1); return *this; }
+
+ /** For optional values the bit is set if the value is present. */
template <class T> PackBits& operator()(const boost::optional<T>& 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<class T> uint32_t packBits(const T& t) {
return pack.getBits();
}
+/** Decode members enabled by Bits */
template <class Decoder, class Bits>
class PackedDecoder {
public:
PackedDecoder(Decoder& d, Bits b) : decode(d), bits(b) {}
- template <class T> PackedDecoder& operator()(T& t) { decode(t); return *this; }
+ template <class T> 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 <class T> PackedDecoder& operator()(boost::optional<T>& 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<T>& w) {
struct Void { template <class S> void serialize(S&) {} };
inline std::ostream& operator<<(std::ostream& o, const Void&) { return o; }
-/** Bit type - bool value with no encoding. */
-struct Bit : Wrapper<bool> {
- template <class S> void serialize(S& s) { s.split(*this); }
- template <class S> void encode(S&) const {}
- template <class S> void decode(S&) { value=true; }
+/** Bit is a presence indicator - an optional value with no encoding. */
+struct Bit : public Wrapper<bool> {
+ Bit(bool b=false) : Wrapper<bool>(b) {}
+ using Wrapper<bool>::operator=;
+ template <class S> void serialize(S& s) { s.split(*this); }
+ template <class S> void encode(S&) const { }
+ template <class S> 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 <iostream>
@@ -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;