00001 #ifndef QPID_SERIALIZER_H
00002 #define QPID_SERIALIZER_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 <limits>
00026 #include <algorithm>
00027 #include "qpid/Exception.h"
00028
00029 namespace qpid {
00030
00036 template <class T> T& serializable(T& t) { return t; }
00037
00039 template <class T, class U> struct SerializablePair {
00040 std::pair<T,U>& value;
00041 SerializablePair(std::pair<T,U>& x) : value(x) {}
00042 template <class S> void serialize(S& s) { s(value.first)(value.second); }
00043 };
00044
00045 template <class T, class U>
00046 SerializablePair<T,U> serializable(std::pair<T,U>& p) {
00047 return SerializablePair<T,U>(p);
00048 }
00049
00055 template <class Derived> class Serializer {
00056 public:
00058 class ScopedLimit {
00059 public:
00060 ScopedLimit(Serializer& s, size_t l)
00061 : serializer(s), save(serializer.setLimit(l)) {}
00062
00063 ~ScopedLimit() { serializer.setAbsLimit(save); }
00064
00065 private:
00066 Serializer& serializer;
00067 size_t save;
00068 };
00069
00070 static size_t maxLimit() { return std::numeric_limits<size_t>::max(); }
00071
00072 Serializer() : bytes(0), limit(maxLimit()) {}
00073
00074 typedef Derived& result_type;
00075
00077 template <class S> struct Ref {
00078 typedef typename S::result_type result_type;
00079 S& s;
00080 Ref(S& ss) : s(ss) {}
00081 template <class T> result_type operator()(T& x) { return s(x); }
00082 template <class T> result_type operator()(const T& x) { return s(x); }
00083 };
00084
00088 template <class S> static Ref<S> ref(S& s) { return Ref<S>(s); }
00089
00091 template <class Iter> Derived& operator()(Iter begin, Iter end) {
00092 std::for_each(begin, end, ref(this->self()));
00093 return self();
00094 }
00095
00099 size_t setLimit(size_t n) {
00100 size_t l=limit;
00101 limit = bytes+n;
00102 return l;
00103 }
00104
00108 size_t bytesRemaining() const {
00109 return limit - bytes;
00110 }
00112 void setAbsLimit(size_t n) {
00113 limit = n;
00114 if (bytes > limit)
00115 throw Exception("Framing error: data overrun");
00116 }
00117
00118 protected:
00119 Derived& self() { return *static_cast<Derived*>(this); }
00120 void addBytes(size_t n) {
00121 size_t newBytes=bytes+n;
00122 if (newBytes > limit)
00123 throw Exception("Framing error: data overrun");
00124 bytes = newBytes;
00125 }
00126
00127 private:
00128 void checkLimit() {
00129 }
00130
00131 size_t bytes;
00132 size_t limit;
00133 };
00134
00141 template <class Derived> class EncoderBase : public Serializer<Derived> {
00142 public:
00143 using Serializer<Derived>::operator();
00144 using Serializer<Derived>::self;
00145
00147 template <class T> Derived& operator()(const T& t) {
00148 serializable(const_cast<T&>(t)).serialize(self()); return self();
00149 }
00150
00152 template <class T> Derived& split(const T& t) {
00153 t.encode(self()); return self();
00154 }
00155 };
00156
00163 template <class Derived> class DecoderBase : public Serializer<Derived> {
00164 public:
00165 using Serializer<Derived>::operator();
00166 using Serializer<Derived>::self;
00167
00169 template <class T> Derived& operator()(T& t) {
00170
00171 serializable(t).serialize(self()); return self();
00172 }
00173
00175 template <class T> Derived& split(T& t) {
00176 t.decode(self()); return self();
00177 }
00178 };
00179
00186 template <class Type, class AsType>
00187 struct SerializeAs {
00188 Type& value;
00189 SerializeAs(Type & t) : value(t) {}
00190 template <class S> void serialize(S& s) { s.split(*this); }
00191 template <class S> void encode(S& s) const { s(AsType(value)); }
00192 template <class S> void decode(S& s) { AsType x; s(x); value=Type(x); }
00193 };
00194
00195 }
00196
00197 #endif