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

00001 #ifndef QPID_PACKER_H
00002 #define QPID_PACKER_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 <boost/optional.hpp>
00026 #include <boost/none.hpp>
00027 
00028 namespace qpid {
00029 namespace amqp_0_10 {
00030 
00032 template <class T> struct SerializableOptional {
00033     boost::optional<T>& optional;
00034     SerializableOptional(boost::optional<T>& x) : optional(x) {}
00035     template <class S> void serialize(S& s) {
00036         if (optional)
00037             s(*optional);
00038     }
00039 };
00040 
00041 }}
00042 
00043 
00044 namespace boost {               // For argument dependent lookup.
00045 
00046 template <class T>
00047 qpid::amqp_0_10::SerializableOptional<T> serializable(boost::optional<T>& x) {
00048     return qpid::amqp_0_10::SerializableOptional<T>(x);
00049 }
00050 
00051 } // namespace boost
00052 
00053 namespace qpid {
00054 namespace amqp_0_10 {
00055 
00059 class PackBits {
00060   public:
00061     PackBits() : bit(1), bits(0) {}
00062 
00063     void setBit() { bits |= bit; bit <<= 1; }
00064     void skipBit() { bit <<= 1; }
00065 
00066     uint32_t getBits() { return bits; }
00067     
00068     template <class T> PackBits& operator()(const T&) { setBit(); return *this; }
00069 
00070     template <class T> PackBits& operator()(const boost::optional<T>& opt) {
00071         opt ? setBit() : skipBit(); return *this;
00072     }
00073 
00074   private:
00075     uint32_t bit;
00076     uint32_t bits;
00077 };
00078 
00080 template<class T> uint32_t packBits(const T& t) {
00081     PackBits pack;
00082     const_cast<T&>(t).serialize(pack);
00083     return pack.getBits();
00084 }
00085 
00086 template <class Decoder, class Bits>
00087 class PackedDecoder {
00088   public:
00089     PackedDecoder(Decoder& d, Bits b) : decode(d), bits(b) {}
00090 
00091     template <class T> PackedDecoder& operator()(T& t) { decode(t); return *this; }
00092     
00093     template <class T> PackedDecoder& operator()(boost::optional<T>& opt) {
00094         if (bits & 1) {
00095             opt = T();          
00096             decode(*opt);
00097         }
00098         else
00099             opt = boost::none;
00100         bits >>= 1;
00101         return *this;
00102     }
00103 
00104   private:
00105     Decoder& decode;
00106     Bits bits;
00107 };
00108 
00110 template <int PackBytes> struct PackBitsType;
00111 template <> struct PackBitsType<1> { typedef uint8_t type; };
00112 template <> struct PackBitsType<2> { typedef uint16_t type; };
00113 template <> struct PackBitsType<4> { typedef uint32_t type; };
00114 
00118 template <class T> class Packer
00119 {
00120   public:
00121     typedef typename PackBitsType<T::PACK>::type Bits;
00122 
00123     Packer(T& t) : data(t) {}
00124 
00125     template <class S> void serialize(S& s) { s.split(*this); }
00126 
00127     template <class S> void encode(S& s) const {
00128         Bits bits = packBits(data);
00129         s.littleEnd(bits);
00130         data.serialize(s);
00131     }
00132 
00133     template <class S> void decode(S& s) {
00134         Bits bits;
00135         s.littleEnd(bits);
00136         PackedDecoder<S, Bits> decode(s, bits);
00137         data.serialize(decode);
00138     }
00139     
00140 
00141   private:
00142     T& data;
00143 };
00144 
00145 }} // namespace qpid::amqp_0_10
00146 
00147 
00148 
00149 #endif  

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