00001 #ifndef QPID_PACKER_H
00002 #define QPID_PACKER_H
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <boost/optional.hpp>
00026 #include <boost/none.hpp>
00027
00028 namespace qpid {
00029 namespace amqp_0_10 {
00030
00032 template <class T> struct SerializableOptional {
00033 boost::optional<T>& optional;
00034 SerializableOptional(boost::optional<T>& x) : optional(x) {}
00035 template <class S> void serialize(S& s) {
00036 if (optional)
00037 s(*optional);
00038 }
00039 };
00040
00041 }}
00042
00043
00044 namespace boost {
00045
00046 template <class T>
00047 qpid::amqp_0_10::SerializableOptional<T> serializable(boost::optional<T>& x) {
00048 return qpid::amqp_0_10::SerializableOptional<T>(x);
00049 }
00050
00051 }
00052
00053 namespace qpid {
00054 namespace amqp_0_10 {
00055
00059 class PackBits {
00060 public:
00061 PackBits() : bit(1), bits(0) {}
00062
00063 void setBit() { bits |= bit; bit <<= 1; }
00064 void skipBit() { bit <<= 1; }
00065
00066 uint32_t getBits() { return bits; }
00067
00068 template <class T> PackBits& operator()(const T&) { setBit(); return *this; }
00069
00070 template <class T> PackBits& operator()(const boost::optional<T>& opt) {
00071 opt ? setBit() : skipBit(); return *this;
00072 }
00073
00074 private:
00075 uint32_t bit;
00076 uint32_t bits;
00077 };
00078
00080 template<class T> uint32_t packBits(const T& t) {
00081 PackBits pack;
00082 const_cast<T&>(t).serialize(pack);
00083 return pack.getBits();
00084 }
00085
00086 template <class Decoder, class Bits>
00087 class PackedDecoder {
00088 public:
00089 PackedDecoder(Decoder& d, Bits b) : decode(d), bits(b) {}
00090
00091 template <class T> PackedDecoder& operator()(T& t) { decode(t); return *this; }
00092
00093 template <class T> PackedDecoder& operator()(boost::optional<T>& opt) {
00094 if (bits & 1) {
00095 opt = T();
00096 decode(*opt);
00097 }
00098 else
00099 opt = boost::none;
00100 bits >>= 1;
00101 return *this;
00102 }
00103
00104 private:
00105 Decoder& decode;
00106 Bits bits;
00107 };
00108
00110 template <int PackBytes> struct PackBitsType;
00111 template <> struct PackBitsType<1> { typedef uint8_t type; };
00112 template <> struct PackBitsType<2> { typedef uint16_t type; };
00113 template <> struct PackBitsType<4> { typedef uint32_t type; };
00114
00118 template <class T> class Packer
00119 {
00120 public:
00121 typedef typename PackBitsType<T::PACK>::type Bits;
00122
00123 Packer(T& t) : data(t) {}
00124
00125 template <class S> void serialize(S& s) { s.split(*this); }
00126
00127 template <class S> void encode(S& s) const {
00128 Bits bits = packBits(data);
00129 s.littleEnd(bits);
00130 data.serialize(s);
00131 }
00132
00133 template <class S> void decode(S& s) {
00134 Bits bits;
00135 s.littleEnd(bits);
00136 PackedDecoder<S, Bits> decode(s, bits);
00137 data.serialize(decode);
00138 }
00139
00140
00141 private:
00142 T& data;
00143 };
00144
00145 }}
00146
00147
00148
00149 #endif