/usr/share/cruisecontrol-bin-2.6.1/projects/qpid-trunk/cpp/src/qpid/amqp_0_10/Codec.h

00001 #ifndef QPID_AMQP_0_10_CODEC_H
00002 #define QPID_AMQP_0_10_CODEC_H
00003 
00004 /*
00005  *
00006  * Licensed to the Apache Software Foundation (ASF) under one
00007  * or more contributor license agreements.  See the NOTICE file
00008  * distributed with this work for additional information
00009  * regarding copyright ownership.  The ASF licenses this file
00010  * to you under the Apache License, Version 2.0 (the
00011  * "License"); you may not use this file except in compliance
00012  * with the License.  You may obtain a copy of the License at
00013  * 
00014  *   http://www.apache.org/licenses/LICENSE-2.0
00015  * 
00016  * Unless required by applicable law or agreed to in writing,
00017  * software distributed under the License is distributed on an
00018  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
00019  * KIND, either express or implied.  See the License for the
00020  * specific language governing permissions and limitations
00021  * under the License.
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         // FIXME aconway 2008-03-10:  wrong encoding, need packing support
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         // FIXME aconway 2008-03-10:  wrong encoding, need packing support
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         // FIXME aconway 2008-04-03: optimize op()(Iter,Iter)
00187         // for Iter with fixed-size value_type:
00188         // distance(begin,end)*sizeof(value_type)
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     // FIXME aconway 2008-03-11: rename to encoder(), decoder()
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 }} // namespace qpid::amqp_0_10
00212 
00213 #endif  

Generated on Thu Apr 10 11:08:17 2008 for Qpid by  doxygen 1.4.7