diff options
| author | Alan Conway <aconway@apache.org> | 2008-02-21 02:58:37 +0000 |
|---|---|---|
| committer | Alan Conway <aconway@apache.org> | 2008-02-21 02:58:37 +0000 |
| commit | cc55340d5d7cf74d045f5f7608aa03c5fa7a4675 (patch) | |
| tree | b4fab5adce9886a328d3f646be674c108503a94a /cpp/src/qpid/amqp_0_10/Codec.h | |
| parent | a00fe37e0854df1bdd9e0187873d3d1c8972eeb8 (diff) | |
| download | qpid-python-cc55340d5d7cf74d045f5f7608aa03c5fa7a4675.tar.gz | |
AMQP 0-10 type system:
- new lightweight templated serialization framework
- all fixed-size built-in types tested and working
- all vbin & str types implemented, tests disabled need to fix encoding.
The following types remain to be implemented:
byte-ranges 2 byte ranges within a 64-bit payload
sequence-set 2 ranged set representation
map 0xa8 4 a mapping of keys to typed values
list 0xa9 4 a series of consecutive type-value pairs
array 0xaa 4 a defined length collection of values of a single type
struct32 0xab 4 a coded struct with a 32-bit size
git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@629679 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp/src/qpid/amqp_0_10/Codec.h')
| -rw-r--r-- | cpp/src/qpid/amqp_0_10/Codec.h | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/cpp/src/qpid/amqp_0_10/Codec.h b/cpp/src/qpid/amqp_0_10/Codec.h new file mode 100644 index 0000000000..e7f35e9288 --- /dev/null +++ b/cpp/src/qpid/amqp_0_10/Codec.h @@ -0,0 +1,187 @@ +#ifndef QPID_AMQP_0_10_CODEC_H +#define QPID_AMQP_0_10_CODEC_H + +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +#include "built_in_types.h" +#include "qpid/Serializer.h" +#include <boost/type_traits/is_integral.hpp> +#include <boost/type_traits/is_float.hpp> +#include <boost/type_traits/is_arithmetic.hpp> +#include <boost/detail/endian.hpp> +#include <boost/ref.hpp> + +namespace qpid { +namespace amqp_0_10 { + +/** + * AMQP 0-10 encoding and decoding. + */ +struct Codec +{ + template <class T> + static inline void endianize(T& value) { + +#ifdef BOOST_LITTLE_ENDIAN + std::reverse((char*)&value, (char*)&value+sizeof(value)); +#else + (void)value; // Avoid unused var warnings. +#endif + } + static inline void endianize(char&) {} + static inline void endianize(uint8_t&) {} + static inline void endianize(int8_t&) {} + + + template <class Out> struct Encode : public ConstSerializer<Encode<Out> > { + Out out; + + Encode(Out o) : out(o) {} + + using ConstSerializer<Encode<Out> >::operator(); + using ConstSerializer<Encode<Out> >::raw; + + template <class T> + typename boost::enable_if<boost::is_integral<T>, Encode&>::type + operator()(const T& x) { T xx(x); endianize(xx); return raw(xx); } + + // FIXME aconway 2008-02-20: correct float encoading + template <class T> + typename boost::enable_if<boost::is_float<T>, Encode&>::type + operator()(const T& x) { return raw(x); } + + + template<class T, class SizeType> + Encode& operator()(const CodableString<T,SizeType>& str) { + (*this)(SizeType(str.size())); + std::for_each(str.begin(), str.end(), *this); + return *this; + } + + private: + friend class ConstSerializer<Encode<Out> >; + + Encode& raw(const void* vp, size_t s) { + char* p = (char*) vp; + std::copy(p, p+s, out); + return *this; + } + + Encode& byte(char x) { out++ = x; return *this; } + }; + + template <class In> struct Decode : public Serializer<Decode<In> > { + In in; + Decode(In i) : in(i) {} + + using Serializer<Decode<In> >::operator(); + using Serializer<Decode<In> >::raw; + + template <class T> + typename boost::enable_if<boost::is_integral<T>, Decode&>::type + operator()(T& x) { + raw(&x, sizeof(x)); + endianize(x); + return *this; + } + + template <class T> + typename boost::enable_if<boost::is_float<T>, Decode&>::type + operator()(T& x) { return raw(&x, sizeof(x)); } + + template<class T, class SizeType> + Decode& operator()(CodableString<T,SizeType>& str) { + SizeType n; + (*this)(n); + str.resize(n); + std::for_each(str.begin(), str.end(), *this); + return *this; + } + + private: + friend class Serializer<Decode<In> >; + + Decode& raw(void* vp, size_t s) { + char* p=(char*)vp; + std::copy(in, in+s, p); + return *this; + } + + Decode& byte(char& x) { x = *in++; return *this; } + }; + + struct Size : public ConstSerializer<Size> { + Size() : size(0) {} + size_t size; + operator size_t() const { return size; } + + using ConstSerializer<Size>::operator(); + using ConstSerializer<Size>::raw; + + template <class T> + typename boost::enable_if<boost::is_arithmetic<T>, Size&>::type + operator()(const T&) { size += sizeof(T); return *this; } + + template <class T, size_t N> + Size& operator()(const boost::array<T,N>&) { + size += sizeof(boost::array<T,N>); + return *this; + } + + template<class T, class SizeType> + Size& operator()(const CodableString<T,SizeType>& str) { + size += sizeof(SizeType) + str.size()*sizeof(T); + return *this; + } + + + private: + friend class ConstSerializer<Size>; + + Size& raw(void*, size_t s) { size += s; return *this; } + + Size& byte(char) { ++size; return *this; } + }; + + template <class Out, class T> + static void encode(Out o, const T& x) { + Encode<Out>encode(o); + encode(x); + } + + template <class In, class T> + static void decode(In i, T& x) { + Decode<In> decode(i); + decode(x); + } + + template <class T> + static size_t size(const T& x) { + Size sz; + sz(x); + return sz; + } +}; + +}} // namespace qpid::amqp_0_10 + +#endif /*!QPID_AMQP_0_10_CODEC_H*/ |
