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

00001 #ifndef QPID_SERIALIZER_H
00002 #define QPID_SERIALIZER_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 <limits>
00026 #include <algorithm>
00027 #include "qpid/Exception.h"     // FIXME aconway 2008-04-03: proper exception class.
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; // unary functor requirement.
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 getLimit() 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"); // FIXME aconway 2008-04-03: proper exception.
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"); // FIXME aconway 2008-04-03: proper exception.
00124         bytes = newBytes;
00125     }
00126     
00127   private:
00128     void checkLimit() {
00129     }
00130         
00131     size_t bytes;               // how many bytes serialized.
00132     size_t limit;               // bytes may not exceed this 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 } // namespace qpid
00196 
00197 #endif  

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