Author: aconway
Date: Thu Apr  3 10:23:34 2008
New Revision: 644413

URL: http://svn.apache.org/viewvc?rev=644413&view=rev
Log:



src/qpid/amqp_0_10/Map.h,.cpp: use preview encoding temporarily.
Misc cleanup for 0-10 encoding.

Modified:
    incubator/qpid/trunk/qpid/cpp/rubygen/0-10/specification.rb
    incubator/qpid/trunk/qpid/cpp/src/qpid/Serializer.h
    incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/Codec.h
    incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/Map.cpp
    incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/Map.h
    incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/PackedCodec.h
    incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/Segment.h
    incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/built_in_types.h
    incubator/qpid/trunk/qpid/cpp/src/tests/amqp_0_10/Map.cpp
    incubator/qpid/trunk/qpid/cpp/src/tests/serialize.cpp

Modified: incubator/qpid/trunk/qpid/cpp/rubygen/0-10/specification.rb
URL: 
http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/rubygen/0-10/specification.rb?rev=644413&r1=644412&r2=644413&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/rubygen/0-10/specification.rb (original)
+++ incubator/qpid/trunk/qpid/cpp/rubygen/0-10/specification.rb Thu Apr  3 
10:23:34 2008
@@ -19,8 +19,8 @@
         genl d.enum.choices.map { |c|
           "#{c.name.constname} = #{c.value}" }.join(",\n")
       }
-      scope("inline SerializableEnum<#{typename}, uint8_t> 
serializable(#{typename}& e) {") {
-        genl "return SerializableEnum<#{typename}>(e);"
+      scope("inline SerializeAs<#{typename}, uint8_t> 
serializable(#{typename}& e) {") {
+        genl "return SerializeAs<#{typename}, uint8_t>(e);"
       }
     else
       genl "typedef #{d.amqp2cpp} #{typename};"

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/Serializer.h
URL: 
http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/Serializer.h?rev=644413&r1=644412&r2=644413&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/Serializer.h (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/Serializer.h Thu Apr  3 10:23:34 2008
@@ -22,82 +22,121 @@
  *
  */
 
-#include <boost/utility/enable_if.hpp>
-#include <boost/type_traits/is_base_and_derived.hpp>
+#include <algorithm>
 
 namespace qpid {
-namespace serialize { 
 
-/** Wrapper to pass serializer functors by reference. */
-template <class S> struct SRef {
-    S& s;
-    SRef(S& ss) : s(ss) {}
-    template <class T> typename S::result_type operator()(T& x) { return s(x); 
}
-    template <class T> typename S::result_type operator()(const T& x) { return 
s(x); }
-};
+/**
+ * Overload for types that do not provide a serialize() member.
+ * It should retrun a wrapper holding a reference to t that implements
+ * serialize()
+ */
+template <class T> T& serializable(T& t) { return t; }
 
-template <class S> SRef<S> ref(S& s) { return SRef<S>(s); }
+/** Serialize std::pair */
+template <class T, class U> struct SerializablePair {
+    std::pair<T,U>& value;
+    SerializablePair(std::pair<T,U>& x) : value(x) {}
+    template <class S> void serialize(S& s) { s(value.first)(value.second); }
+};
 
-// FIXME aconway 2008-03-03: Document.
-// Encoder/Decoder concept: add op() for primitive types, raw(),
-// op()(Iter, Iter). Note split, encode, decode.
-// 
+template <class T, class U>
+SerializablePair<T,U> serializable(std::pair<T,U>& p) {
+    return SerializablePair<T,U>(p);
+}
+
+/**
+ * Base class for all serializers.
+ * Derived serializers inherit from either Encoder or Decoder.
+ * Serializers can be used as functors or static_visitors.
+ */
+template <class Derived> class Serializer {
+  public:
+    typedef Derived& result_type; // unary functor requirement.
 
-// FIXME aconway 2008-03-09: document - non-intrusive serialzation.
-// Default rule calls member. Enums must provide an override rule.
+    /** Wrapper functor to pass serializer functors by reference. */
+    template <class S> struct Ref {
+        typedef  typename S::result_type result_type;
+        S& s;
+        Ref(S& ss) : s(ss) {}
+        template <class T> result_type operator()(T& x) { return s(x); }
+        template <class T> result_type operator()(const T& x) { return s(x); }
+    };
+
+    /** Reference wrapper to pass serializers by reference,
+     * e.g. to std:: functions that take functors.
+     */
+    template <class S> static Ref<S> ref(S& s) { return Ref<S>(s); }
+
+    /** Generic rule to serialize an iterator range */
+    template <class Iter> Derived& operator()(Iter begin, Iter end) {
+        std::for_each(begin, end, ref(this->self()));
+        return self();
+    }
 
-/** Overload for types that do not provide a serialize() member.*/
-template <class T> T& serializable(T& t) { return t; }
+  protected:
+    Derived& self() { return *static_cast<Derived*>(this); }
+};
 
-template <class Derived> class Encoder {
+/**
+ * Base class for encoders, provides generic encode functions.
+ *
+ * A derived encoder must provide operator(const T&) to encode all
+ * primitive types T.
+ */
+template <class Derived> class EncoderBase : public Serializer<Derived> {
   public:
-    typedef Derived& result_type; // unary functor requirement.
-
-    /** Default op() calls serializable() free function */
-    template <class T>
-    Derived& operator()(const T& t) {
+    using Serializer<Derived>::operator();
+    using Serializer<Derived>::self;
+    
+    /** Default op() for non-primitive types. */
+    template <class T> Derived& operator()(const T& t) {
         serializable(const_cast<T&>(t)).serialize(self()); return self();
     }
 
     /** Split serialize() into encode()/decode() */
-    template <class T>
-    Derived& split(const T& t) { t.encode(self()); return self(); }
-    
-  private:
-    Derived& self() { return *static_cast<Derived*>(this); }
+    template <class T> Derived& split(const T& t) {
+        t.encode(self()); return self();
+    }
 };
 
-template <class Derived> class Decoder {
+/**
+ * Base class for decoders, provides generic decode functions.
+ *
+ * A derived encoder must provide operator(T&) to encode all
+ * primitive types T.
+ */
+template <class Derived> class DecoderBase : public Serializer<Derived> {
   public:
-    typedef Derived& result_type; // unary functor requirement.
+    using Serializer<Derived>::operator();
+    using Serializer<Derived>::self;
 
-    /** Default op() calls serializable() free function */
-    template <class T>
-    Derived& operator()(T& t) {
+    /** Default op() for non-primitive types. */
+    template <class T> Derived& operator()(T& t) {
         serializable(t).serialize(self()); return self();
     }
 
     /** Split serialize() into encode()/decode() */
-    template <class T>
-    Derived& split(T& t) { t.decode(self()); return self(); }
-    
-
-  private:
-    Derived& self() { return *static_cast<Derived*>(this); }
+    template <class T> Derived& split(T& t) {
+        t.decode(self()); return self();
+    }
 };
 
-/** Serialize a type by converting it to/from another type */
+/** Serialize a type by converting it to/from another type.
+ * To serialize type Foo by converting to/from type Bar create
+ * a serializable() overload like this:
+ * 
+ * SerializeAs<Foo,Bar> serializable(Foo& t) { return SerializeAs<Foo,Bar>(t); 
}
+ */
 template <class Type, class AsType>
 struct SerializeAs {
     Type& value;
     SerializeAs(Type & t) : value(t) {}
     template <class S> void serialize(S& s) { s.split(*this); }
     template <class S> void encode(S& s) const { s(AsType(value)); }
-    template <class S> void decode(S& s) { AsType x; s(x); value=x; }
+    template <class S> void decode(S& s) { AsType x; s(x); value=Type(x); }
 };
 
-}} // namespace qpid::serialize
+} // namespace qpid
 
-// FIXME aconway 2008-03-09: rename to serialize.h
-// 
 #endif  /*!QPID_SERIALIZER_H*/

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/Codec.h
URL: 
http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/Codec.h?rev=644413&r1=644412&r2=644413&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/Codec.h (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/Codec.h Thu Apr  3 
10:23:34 2008
@@ -29,6 +29,7 @@
 #include <boost/type_traits/is_arithmetic.hpp>
 #include <boost/detail/endian.hpp>
 #include <boost/static_assert.hpp>
+#include <iterator>
 
 namespace qpid {
 namespace amqp_0_10 {
@@ -46,17 +47,14 @@
  * AMQP 0-10 encoding and decoding.
  */
 struct Codec {
-    // FIXME aconway 2008-02-29: drop this wrapper, rename to
-    // IteratorEncoder, IteratorDecoder?
-
     /** Encode to an output byte iterator */
     template <class OutIter>
-    class Encoder : public serialize::Encoder<Encoder<OutIter> >
+    class Encoder : public EncoderBase<Encoder<OutIter> >
     {
       public:
         Encoder(OutIter o) : out(o) {}
 
-        using serialize::Encoder<Encoder<OutIter> >::operator();
+        using EncoderBase<Encoder<OutIter> >::operator();
 
         // FIXME aconway 2008-03-10:  wrong encoding, need packing support
         Encoder& operator()(bool x) { *out++=x; return *this;} 
@@ -77,14 +75,8 @@
         Encoder& operator()(double x) { return endian(x); }
 
 
-        template <class Iter> Encoder& operator()(Iter begin, Iter end) {
-            std::for_each(begin, end, serialize::ref(*this));
-            return *this;
-        }
-
         void raw(const void* p, size_t n) {
-            std::copy((const char*)p, (const char*)p+n, out);
-            out += n;
+            out = std::copy((const char*)p, (const char*)p+n, out);
         }
 
         OutIter pos() const { return out; }
@@ -99,11 +91,13 @@
     };
 
     template <class InIter>
-    class Decoder : public serialize::Decoder<Decoder<InIter> > {
+    class Decoder : public DecoderBase<Decoder<InIter> > {
       public:
+        typedef InIter Iterator;
+        
         Decoder(InIter i) : in(i) {}
 
-        using serialize::Decoder<Decoder<InIter> >::operator();
+        using DecoderBase<Decoder<InIter> >::operator();
         
         // FIXME aconway 2008-03-10:  wrong encoding, need packing support
         Decoder& operator()(bool& x) { x=*in++; return *this; }
@@ -123,14 +117,9 @@
         Decoder& operator()(float& x) { return endian(x); }
         Decoder& operator()(double& x) { return endian(x); }
 
-        template <class Iter> Decoder& operator()(Iter begin, Iter end) {
-            std::for_each(begin, end, serialize::ref(*this));
-            return *this;
-        }
-
         void raw(void *p, size_t n) {
             std::copy(in, in+n, (char*)p);
-            in += n;
+            std::advance(in, n);
         }
 
         InIter pos() const { return in; }
@@ -145,13 +134,13 @@
     };
 
     
-    class Size : public serialize::Encoder<Size> {
+    class Size : public EncoderBase<Size> {
       public:
         Size() : size(0) {}
 
         operator size_t() const { return size; }
 
-        using serialize::Encoder<Size>::operator();
+        using EncoderBase<Size>::operator();
 
         // FIXME aconway 2008-03-10:  wrong encoding, need packing support
         Size& operator()(bool x)  { size += sizeof(x); return *this; }
@@ -171,12 +160,9 @@
         Size& operator()(float x)  { size += sizeof(x); return *this; }
         Size& operator()(double x)  { size += sizeof(x); return *this; }
 
-        // FIXME aconway 2008-04-02: enable-if optimized (iter,iter) for
-        // iter on fixed-size type.
-        template <class Iter> Size& operator()(Iter begin, Iter end) {
-            std::for_each(begin, end, serialize::ref(*this));
-            return *this;
-        }
+        // FIXME aconway 2008-04-03: optimize op()(Iter,Iter)
+        // for Iter with fixed-size value_type:
+        // distance(begin,end)*sizeof(value_type)
 
         void raw(const void*, size_t n){ size += n; }
 

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/Map.cpp
URL: 
http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/Map.cpp?rev=644413&r1=644412&r2=644413&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/Map.cpp (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/Map.cpp Thu Apr  3 
10:23:34 2008
@@ -18,6 +18,7 @@
  * under the License.
  *
  */
+#include "qpid/amqp_0_10/specification.h" // for error constants.
 #include "Map.h"
 #include <ostream>
 
@@ -57,12 +58,12 @@
 }
 
 uint32_t Map::contentSize() const {
-    uint32_t result=4;          // uint32_t count 
-    for (const_iterator i=begin(); i != end(); ++i) {
-        result += Codec::size(i->first);
-        result += Codec::size(i->second);
-    }
-    return result;
+    // FIXME aconway 2008-04-03: preview to 0-10 mapping: +4 for count.
+    return /*4 +*/ Codec::Size()(begin(), end()); 
+}
+
+void Map::throwInvalidArg() {
+    throw SessionException(execution::INVALID_ARGUMENT, "Invalid map 
encoding");
 }
 
 }} // namespace qpid::amqp_0_10

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/Map.h
URL: 
http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/Map.h?rev=644413&r1=644412&r2=644413&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/Map.h (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/Map.h Thu Apr  3 10:23:34 
2008
@@ -85,14 +85,13 @@
   public:
     template <class S> void serialize(S& s) { s.split(*this); }
     template <class S> void encode(S& s) const;
-
-    // FIXME aconway 2008-04-02: better separation for size calcultion
-    // support for static size, optimized iterator size calc.
+    // Shortcut calculation for size.
     void encode(Codec::Size& s) const  { s.raw(0, contentSize() + 4/*size*/); }
 
     template <class S> void decode(S& s);
     
   private:
+    static void throwInvalidArg();
     uint32_t contentSize() const;
 };
 
@@ -157,18 +156,26 @@
 }
 
 template <class S> void Map::encode(S& s) const {
-    s(contentSize())(uint32_t(size())); // size, count
+    // FIXME aconway 2008-04-03: replace preview mapping with 0-10 mapping:
+    // s(contentSize())(uint32_t(size())); // size, count
+    s(contentSize());
     for (const_iterator i = begin(); i != end(); ++i)
         s(i->first)(i->second); // key (type value)
 }
 
 template <class S> void Map::decode(S& s) {
-    uint32_t cSize, count;
-    // FIXME aconway 2008-04-02: runtime check that we consume exactly cSize.
-    s(cSize)(count);
-    for ( ; count > 0; --count) {
+    uint32_t cSize /*, count*/;
+    // FIXME aconway 2008-04-03: replace preview mapping with 0-10 mapping:
+    // s(contentSize())(uint32_t(size())); // size, count
+    // s(cSize)(count);
+    s(cSize);
+    typename S::Iterator start = s.pos();
+    // FIXME aconway 2008-04-03:  replace preview with 0-10:
+    // for ( ; count > 0; --count) {
+    while (uint32_t(std::distance(start, s.pos())) < cSize) {
         key_type k; MapValue v;
         s(k)(v);
+        if (uint32_t(std::distance(start, s.pos())) > cSize) throwInvalidArg();
         insert(value_type(k,v));
     }
 }

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/PackedCodec.h
URL: 
http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/PackedCodec.h?rev=644413&r1=644412&r2=644413&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/PackedCodec.h (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/PackedCodec.h Thu Apr  3 
10:23:34 2008
@@ -34,7 +34,7 @@
 struct PackedCodec {
     template <class Bits, class InnerDecoder>
     class Decoder :
-        public serialize::Decoder<PackedCodec::Decoder<Bits, InnerDecoder> >
+        public DecoderBase<PackedCodec::Decoder<Bits, InnerDecoder> >
     {
       public:
         Decoder(Bits b, const InnerDecoder& d)

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/Segment.h
URL: 
http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/Segment.h?rev=644413&r1=644412&r2=644413&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/Segment.h (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/Segment.h Thu Apr  3 
10:23:34 2008
@@ -106,6 +106,7 @@
         p += n;
         skip_empty();
     }
+    
     void skip_empty() {
         invariant();
         while (p == i->end() && i != frames->end())

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/built_in_types.h
URL: 
http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/built_in_types.h?rev=644413&r1=644412&r2=644413&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/built_in_types.h (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/built_in_types.h Thu Apr  
3 10:23:34 2008
@@ -21,11 +21,12 @@
  *
  */
 
-#include "Decimal.h"
-#include "SerializableString.h"
+#include "qpid/Serializer.h"
 #include "qpid/framing/SequenceNumber.h"
 #include "qpid/framing/Uuid.h"
 #include "qpid/sys/Time.h"
+#include "Decimal.h"
+#include "SerializableString.h"
 #include <boost/array.hpp>
 #include <boost/range/iterator_range.hpp>
 #include <string>
@@ -153,21 +154,12 @@
 inline std::ostream& operator<<(std::ostream& o, const List&) { return o; }
 inline std::ostream& operator<<(std::ostream& o, const Struct32&) { return o; }
 
-/** Serialization helper for enums */
-template <class Enum, class Int=uint8_t>
-struct SerializableEnum {
-    Enum& value;
-    SerializableEnum(Enum & e) : value(e) {}
-    template <class S> void serialize(S& s) { s.split(*this); }
-    template <class S> void encode(S& s) const { s(Int(value)); }
-    template <class S> void decode(S& s) { Int i; s(i); value=Enum(i); }
-};
-
 enum SegmentType { CONTROL, COMMAND, HEADER, BODY };
 
-inline SerializableEnum<SegmentType> serializable(SegmentType& st) {
-    return SerializableEnum<SegmentType>(st);
+inline SerializeAs<SegmentType, uint8_t> serializable(SegmentType& st) {
+    return SerializeAs<SegmentType, uint8_t>(st);
 }
+
 
 }} // namespace qpid::amqp_0_10
 

Modified: incubator/qpid/trunk/qpid/cpp/src/tests/amqp_0_10/Map.cpp
URL: 
http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/tests/amqp_0_10/Map.cpp?rev=644413&r1=644412&r2=644413&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/tests/amqp_0_10/Map.cpp (original)
+++ incubator/qpid/trunk/qpid/cpp/src/tests/amqp_0_10/Map.cpp Thu Apr  3 
10:23:34 2008
@@ -26,11 +26,6 @@
 using namespace qpid::amqp_0_10;
 using namespace std;
 
-namespace std {
-// Dummy += for back inserters so we can use them with the decoder.
-template <class C> back_insert_iterator<C>& 
operator+=(back_insert_iterator<C>& bi, size_t) { return bi; }
-}
-
 QPID_AUTO_TEST_SUITE(MapTestSuite)
 
  BOOST_AUTO_TEST_CASE(testGetSet) {

Modified: incubator/qpid/trunk/qpid/cpp/src/tests/serialize.cpp
URL: 
http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/tests/serialize.cpp?rev=644413&r1=644412&r2=644413&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/tests/serialize.cpp (original)
+++ incubator/qpid/trunk/qpid/cpp/src/tests/serialize.cpp Thu Apr  3 10:23:34 
2008
@@ -60,14 +60,7 @@
 
 } // qpid
 
-namespace std {
-// Dummy += for back inserters so we can use them with the decoder.
-template <class C> back_insert_iterator<C>& 
operator+=(back_insert_iterator<C>& bi, size_t) { return bi; }
-}
-
 QPID_AUTO_TEST_SUITE(SerializeTestSuite)
-
-
 
 using namespace std;
 namespace mpl=boost::mpl;


Reply via email to