00001 #ifndef QPID_AMQP_0_10_CODEC_H
00002 #define QPID_AMQP_0_10_CODEC_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 "built_in_types.h"
00026 #include "qpid/Serializer.h"
00027 #include <boost/type_traits/is_integral.hpp>
00028 #include <boost/type_traits/is_float.hpp>
00029 #include <boost/type_traits/is_arithmetic.hpp>
00030 #include <boost/detail/endian.hpp>
00031 #include <boost/static_assert.hpp>
00032 #include <iterator>
00033
00034 namespace qpid {
00035 namespace amqp_0_10 {
00036
00037 template <class T> void reverse(T& t) {
00038 char*p =reinterpret_cast<char*>(&t);
00039 std::reverse(p, p+sizeof(T));
00040 }
00041
00042 #ifdef BOOST_LITTLE_ENDIAN
00043 template <class T> void bigEndian(T& t) { reverse(t); }
00044 template <class T> void littleEndian(T&) {}
00045 #else
00046 template <class T> void littleEndian(T& t) { reverse(t); }
00047 template <class T> void bigEndian(T&) {}
00048 #endif
00049
00053 struct Codec {
00055 template <class OutIter>
00056 class Encoder : public EncoderBase<Encoder<OutIter> >
00057 {
00058 public:
00059 typedef EncoderBase<Encoder<OutIter> > Base;
00060 typedef OutIter Iterator;
00061
00062 Encoder(OutIter o, size_t limit=Base::maxLimit()) : out(o) {
00063 this->setLimit(limit);
00064 }
00065
00066 using EncoderBase<Encoder<OutIter> >::operator();
00067
00068 Encoder& operator()(bool x) { raw(x); return *this;}
00069 Encoder& operator()(char x) { raw(x); return *this; }
00070 Encoder& operator()(int8_t x) { raw(x); return *this; }
00071 Encoder& operator()(uint8_t x) { raw(x); return *this; }
00072
00073 Encoder& operator()(int16_t x) { return networkByteOrder(x); }
00074 Encoder& operator()(int32_t x) { return networkByteOrder(x); }
00075 Encoder& operator()(int64_t x) { return networkByteOrder(x); }
00076
00077 Encoder& operator()(uint16_t x) { return networkByteOrder(x); }
00078 Encoder& operator()(uint32_t x) { return networkByteOrder(x); }
00079 Encoder& operator()(uint64_t x) { return networkByteOrder(x); }
00080
00081 Encoder& operator()(float x) { return networkByteOrder(x); }
00082 Encoder& operator()(double x) { return networkByteOrder(x); }
00083
00084 void raw(const void* p, size_t n) {
00085 this->addBytes(n);
00086 out = std::copy((const char*)p, (const char*)p+n, out);
00087 }
00088
00089 void raw(char b) { this->addBytes(1); *out++=b; }
00090
00091 template <class T> Encoder& littleEnd(T x) {
00092 littleEndian(x); raw(&x, sizeof(x)); return *this;
00093 }
00094
00095 OutIter pos() const { return out; }
00096
00097 private:
00098
00099 template <class T> Encoder& networkByteOrder(T x) {
00100 bigEndian(x); raw(&x, sizeof(x)); return *this;
00101 }
00102
00103 OutIter out;
00104 };
00105
00106 template <class InIter>
00107 class Decoder : public DecoderBase<Decoder<InIter> > {
00108 public:
00109 typedef DecoderBase<Decoder<InIter> > Base;
00110 typedef InIter Iterator;
00111
00112 Decoder(InIter i, size_t limit=Base::maxLimit()) : in(i) {
00113 this->setLimit(limit);
00114 }
00115
00116 using DecoderBase<Decoder<InIter> >::operator();
00117
00118
00119 Decoder& operator()(bool& x) { raw((char&)x); return *this; }
00120
00121 Decoder& operator()(char& x) { raw((char&)x); return *this; }
00122 Decoder& operator()(int8_t& x) { raw((char&)x); return *this; }
00123 Decoder& operator()(uint8_t& x) { raw((char&)x); return *this; }
00124
00125 Decoder& operator()(int16_t& x) { return networkByteOrder(x); }
00126 Decoder& operator()(int32_t& x) { return networkByteOrder(x); }
00127 Decoder& operator()(int64_t& x) { return networkByteOrder(x); }
00128
00129 Decoder& operator()(uint16_t& x) { return networkByteOrder(x); }
00130 Decoder& operator()(uint32_t& x) { return networkByteOrder(x); }
00131 Decoder& operator()(uint64_t& x) { return networkByteOrder(x); }
00132
00133 Decoder& operator()(float& x) { return networkByteOrder(x); }
00134 Decoder& operator()(double& x) { return networkByteOrder(x); }
00135
00136 void raw(void *p, size_t n) {
00137 this->addBytes(n);
00138 std::copy(in, in+n, (char*)p);
00139 std::advance(in, n);
00140 }
00141
00142 void raw(char &b) { this->addBytes(1); b=*in++; }
00143
00144 template <class T> Decoder& littleEnd(T& x) {
00145 raw(&x, sizeof(x)); littleEndian(x); return *this;
00146 }
00147
00148 InIter pos() const { return in; }
00149
00150 private:
00151
00152 template <class T> Decoder& networkByteOrder(T& x) {
00153 raw(&x, sizeof(x)); bigEndian(x); return *this;
00154 }
00155
00156 InIter in;
00157 };
00158
00159
00160 class Size : public EncoderBase<Size> {
00161 public:
00162 Size() : size(0) {}
00163
00164 operator size_t() const { return size; }
00165
00166 using EncoderBase<Size>::operator();
00167
00168
00169 Size& operator()(bool x) { size += sizeof(x); return *this; }
00170
00171 Size& operator()(char x) { size += sizeof(x); return *this; }
00172 Size& operator()(int8_t x) { size += sizeof(x); return *this; }
00173 Size& operator()(uint8_t x) { size += sizeof(x); return *this; }
00174
00175 Size& operator()(int16_t x) { size += sizeof(x); return *this; }
00176 Size& operator()(int32_t x) { size += sizeof(x); return *this; }
00177 Size& operator()(int64_t x) { size += sizeof(x); return *this; }
00178
00179 Size& operator()(uint16_t x) { size += sizeof(x); return *this; }
00180 Size& operator()(uint32_t x) { size += sizeof(x); return *this; }
00181 Size& operator()(uint64_t x) { size += sizeof(x); return *this; }
00182
00183 Size& operator()(float x) { size += sizeof(x); return *this; }
00184 Size& operator()(double x) { size += sizeof(x); return *this; }
00185
00186
00187
00188
00189
00190 void raw(const void*, size_t n){ size += n; }
00191
00192 template <class T> Size& littleEnd(T) { size+= sizeof(T); return *this; }
00193
00194 private:
00195 size_t size;
00196 };
00197
00198
00199 template <class InIter> static Decoder<InIter> decode(const InIter &i) {
00200 return Decoder<InIter>(i);
00201 }
00202
00203 template <class OutIter> static Encoder<OutIter> encode(OutIter i) {
00204 return Encoder<OutIter>(i);
00205 }
00206
00207 template <class T> static size_t size(const T& x) { return Size()(x); }
00208 template <class Iter> static size_t size(const Iter& a, const Iter& z) { return Size()(a,z); }
00209 };
00210
00211 }}
00212
00213 #endif