Author: aconway
Date: Thu Apr  3 06:27:07 2008
New Revision: 644308

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

amqp_0_10/built_in_types.h
 - generic Wrapper template for making distinct types.  
 - added Bit - bool wrapper with empty encode/decode.

amqp_0_10/complex_types.h:
 - Added constants SIZE=0, PACK=2 to Action base class.

amqp_0_10/PackedCodec.h:
 - Decode packed struct fields according to the packing bits.

Added:
    incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/PackedCodec.h   (with 
props)
Modified:
    incubator/qpid/trunk/qpid/cpp/src/Makefile.am
    incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/Codec.h
    incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/built_in_types.h
    incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/complex_types.h
    incubator/qpid/trunk/qpid/cpp/src/tests/serialize.cpp

Modified: incubator/qpid/trunk/qpid/cpp/src/Makefile.am
URL: 
http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/Makefile.am?rev=644308&r1=644307&r2=644308&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/Makefile.am (original)
+++ incubator/qpid/trunk/qpid/cpp/src/Makefile.am Thu Apr  3 06:27:07 2008
@@ -109,6 +109,7 @@
   qpid/amqp_0_10/complex_types.cpp \
   qpid/amqp_0_10/Holder.h \
   qpid/amqp_0_10/Codec.h \
+  qpid/amqp_0_10/PackedCodec.h \
   qpid/amqp_0_10/Decimal.h \
   qpid/amqp_0_10/Frame.h \
   qpid/amqp_0_10/Segment.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=644308&r1=644307&r2=644308&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 
06:27:07 2008
@@ -51,33 +51,33 @@
 
     /** Encode to an output byte iterator */
     template <class OutIter>
-    class Encode : public serialize::Encoder<Encode<OutIter> >
+    class Encoder : public serialize::Encoder<Encoder<OutIter> >
     {
       public:
-        Encode(OutIter o) : out(o) {}
+        Encoder(OutIter o) : out(o) {}
 
-        using serialize::Encoder<Encode<OutIter> >::operator();
+        using serialize::Encoder<Encoder<OutIter> >::operator();
 
         // FIXME aconway 2008-03-10:  wrong encoding, need packing support
-        Encode& operator()(bool x) { *out++=x; return *this;} 
+        Encoder& operator()(bool x) { *out++=x; return *this;} 
 
-        Encode& operator()(char x) { *out++=x; return *this; }
-        Encode& operator()(int8_t x) { *out++=x; return *this; }
-        Encode& operator()(uint8_t x) { *out++=x; return *this; }
+        Encoder& operator()(char x) { *out++=x; return *this; }
+        Encoder& operator()(int8_t x) { *out++=x; return *this; }
+        Encoder& operator()(uint8_t x) { *out++=x; return *this; }
 
-        Encode& operator()(int16_t x) { return endian(x); }
-        Encode& operator()(int32_t x) { return endian(x); }
-        Encode& operator()(int64_t x) { return endian(x); }
+        Encoder& operator()(int16_t x) { return endian(x); }
+        Encoder& operator()(int32_t x) { return endian(x); }
+        Encoder& operator()(int64_t x) { return endian(x); }
 
-        Encode& operator()(uint16_t x) { return endian(x); }
-        Encode& operator()(uint32_t x) { return endian(x); }
-        Encode& operator()(uint64_t x) { return endian(x); }
+        Encoder& operator()(uint16_t x) { return endian(x); }
+        Encoder& operator()(uint32_t x) { return endian(x); }
+        Encoder& operator()(uint64_t x) { return endian(x); }
 
-        Encode& operator()(float x) { return endian(x); }
-        Encode& operator()(double x) { return endian(x); }
+        Encoder& operator()(float x) { return endian(x); }
+        Encoder& operator()(double x) { return endian(x); }
 
 
-        template <class Iter> Encode& operator()(Iter begin, Iter end) {
+        template <class Iter> Encoder& operator()(Iter begin, Iter end) {
             std::for_each(begin, end, serialize::ref(*this));
             return *this;
         }
@@ -91,7 +91,7 @@
 
       private:
 
-        template <class T> Encode& endian(T x) {
+        template <class T> Encoder& endian(T x) {
             endianize(x); raw(&x, sizeof(x)); return *this;
         }
 
@@ -99,31 +99,31 @@
     };
 
     template <class InIter>
-    class Decode : public serialize::Decoder<Decode<InIter> > {
+    class Decoder : public serialize::Decoder<Decoder<InIter> > {
       public:
-        Decode(InIter i) : in(i) {}
+        Decoder(InIter i) : in(i) {}
 
-        using serialize::Decoder<Decode<InIter> >::operator();
+        using serialize::Decoder<Decoder<InIter> >::operator();
         
         // FIXME aconway 2008-03-10:  wrong encoding, need packing support
-        Decode& operator()(bool& x) { x=*in++; return *this; }
+        Decoder& operator()(bool& x) { x=*in++; return *this; }
 
-        Decode& operator()(char& x) { x=*in++; return *this; }
-        Decode& operator()(int8_t& x) { x=*in++; return *this; }
-        Decode& operator()(uint8_t& x) { x=*in++; return *this; }
+        Decoder& operator()(char& x) { x=*in++; return *this; }
+        Decoder& operator()(int8_t& x) { x=*in++; return *this; }
+        Decoder& operator()(uint8_t& x) { x=*in++; return *this; }
 
-        Decode& operator()(int16_t& x) { return endian(x); }
-        Decode& operator()(int32_t& x) { return endian(x); }
-        Decode& operator()(int64_t& x) { return endian(x); }
+        Decoder& operator()(int16_t& x) { return endian(x); }
+        Decoder& operator()(int32_t& x) { return endian(x); }
+        Decoder& operator()(int64_t& x) { return endian(x); }
 
-        Decode& operator()(uint16_t& x) { return endian(x); }
-        Decode& operator()(uint32_t& x) { return endian(x); }
-        Decode& operator()(uint64_t& x) { return endian(x); }
+        Decoder& operator()(uint16_t& x) { return endian(x); }
+        Decoder& operator()(uint32_t& x) { return endian(x); }
+        Decoder& operator()(uint64_t& x) { return endian(x); }
 
-        Decode& operator()(float& x) { return endian(x); }
-        Decode& operator()(double& x) { return endian(x); }
+        Decoder& operator()(float& x) { return endian(x); }
+        Decoder& operator()(double& x) { return endian(x); }
 
-        template <class Iter> Decode& operator()(Iter begin, Iter end) {
+        template <class Iter> Decoder& operator()(Iter begin, Iter end) {
             std::for_each(begin, end, serialize::ref(*this));
             return *this;
         }
@@ -137,7 +137,7 @@
 
       private:
 
-        template <class T> Decode& endian(T& x) {
+        template <class T> Decoder& endian(T& x) {
             raw(&x, sizeof(x)); endianize(x); return *this;
         }
 
@@ -185,12 +185,12 @@
     };
 
     // FIXME aconway 2008-03-11: rename to encoder(), decoder()
-    template <class InIter> static Decode<InIter> decode(const InIter &i) {
-        return Decode<InIter>(i);
+    template <class InIter> static Decoder<InIter> decode(const InIter &i) {
+        return Decoder<InIter>(i);
     }
 
-    template <class OutIter> static Encode<OutIter> encode(OutIter i) {
-        return Encode<OutIter>(i);
+    template <class OutIter> static Encoder<OutIter> encode(OutIter i) {
+        return Encoder<OutIter>(i);
     }
 
     template <class T> static size_t size(const T& x) { return Size()(x); }

Added: 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=644308&view=auto
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/PackedCodec.h (added)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/PackedCodec.h Thu Apr  3 
06:27:07 2008
@@ -0,0 +1,79 @@
+#ifndef QPID_AMQP_0_10_PACKEDCODEC_H
+#define QPID_AMQP_0_10_PACKEDCODEC_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 "Codec.h"
+
+namespace qpid {
+namespace amqp_0_10 {
+
+/**
+ * Packed encoding/decoding. Process or ignore fields based on
+ * packing bits.
+ */
+struct PackedCodec {
+    template <class Bits, class InnerDecoder>
+    class Decoder :
+        public serialize::Decoder<PackedCodec::Decoder<Bits, InnerDecoder> >
+    {
+      public:
+        Decoder(Bits b, const InnerDecoder& d)
+            : bits(b), decode(const_cast<InnerDecoder&>(d)) {}
+
+        // Decode if pack bit is set.
+        template<class T> Decoder& operator()(T& t) {
+            if (bits & 1)
+                decode(t);
+            else
+                t = T();        // FIXME aconway 2008-04-02: see below
+            bits >>= 1;
+            return *this;
+        }
+        Bits bits;
+        InnerDecoder& decode;
+    };
+
+    template <class Bits, class InnerDecoder>
+    static Decoder<Bits, InnerDecoder> decode(Bits b, const InnerDecoder& d) {
+        return Decoder<Bits, InnerDecoder>(b,d);
+    }
+
+    // FIXME aconway 2008-04-02: Incorrect packed semantics.
+    // Current implementation is:
+    // - decode value if packed bit set, else default initialize value.
+    // - encode always encode values
+    // - size count all values.
+    // Correct implementation:
+    // - optional value of type T is mapped to boost::optional<T>
+    // - decode value if packed bit set, else value=boost::none
+    // - PackedCodec::Encoder collect packing bits (1 unless == boost::none)
+    //   Codec::Encoder optional skip if none
+    // - size: count only non-none values.
+    // Note we don't encode/decodde the pack bits themselves here, that
+    // happens in the Holder. Holders handle size, count & pack attributes.
+};
+
+
+}} // namespace qpid::amqp_0_10
+
+#endif  /*!QPID_AMQP_0_10_PACKEDCODEC_H*/

Propchange: incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/PackedCodec.h
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/PackedCodec.h
------------------------------------------------------------------------------
    svn:keywords = Rev Date

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=644308&r1=644307&r2=644308&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 06:27:07 2008
@@ -35,16 +35,43 @@
 
 /[EMAIL PROTECTED] Mapping from built-in AMQP types to C++ types */
 
+
 namespace qpid {
 namespace amqp_0_10 {
 
-// Fixed size types
-struct EmptyType { template <class S> void serialize(S&) {} };
-inline std::ostream& operator<<(std::ostream& o, const EmptyType&) { return o; 
} 
+/** Wrapper that behaves like type T but is a distinct type for
+ * overloading purposes. Unique allows multiple distinc wrappers.
+ */
+template <class T, int Unique=0> struct Wrapper {
+    T value;
+    Wrapper() {}
+    Wrapper(const T& x) : value(x) {}
+    Wrapper& operator=(const T& x) { value=x; return *this; }
+    operator T&() { return value; }
+    operator const T&() const { return value; }
+    template <class S> void serialize(S& s) { s(value); }
+};
+
+template<class T>
+inline std::ostream& operator<<(std::ostream& o, const Wrapper<T>& w) {
+    return o << w.value;
+}
 
-struct Void : public EmptyType {};
-struct  Bit : public EmptyType {};
+/** Void type */
+struct Void { template <class S> void serialize(S&) {} };
+inline std::ostream& operator<<(std::ostream& o, const Void&) { return o; } 
 
+/** Bit type - bool value with no encoding. */
+struct  Bit : Wrapper<bool> {
+    template <class S> void serialize(S& s) { s.split(*this); }
+    template <class S> void encode(S&) const {}
+    template <class S> void decode(S&) { value=true; }
+};
+inline std::ostream& operator<<(std::ostream& o, const Bit& b) {
+    return o << b.value;
+}
+
+// Fixed size types
 typedef bool Boolean;
 typedef char Char;
 typedef int8_t Int8;
@@ -55,15 +82,7 @@
 typedef uint16_t Uint16;
 typedef uint32_t Uint32;
 typedef uint64_t Uint64;
-
-// A struct to be distinct from the other 32 bit integrals.
-struct CharUtf32 {
-    uint32_t value;
-    CharUtf32(uint32_t n=0) : value(n) {}
-    operator uint32_t&() { return value; }
-    operator const uint32_t&() const { return value; }
-    template <class S> void serialize(S& s) { s(value); }
-};
+typedef Wrapper<uint32_t> CharUtf32;
 
 template <size_t N> struct Bin : public boost::array<char, N> {
     template <class S> void serialize(S& s) { s.raw(this->begin(), 
this->size()); }

Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/complex_types.h
URL: 
http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/complex_types.h?rev=644308&r1=644307&r2=644308&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/complex_types.h (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/amqp_0_10/complex_types.h Thu Apr  3 
06:27:07 2008
@@ -42,7 +42,7 @@
 struct Command;
 struct Control;
 
-struct Action {  // Marker for commands & controls
+struct Action {  // Base for commands & controls
     virtual ~Action() {}
     virtual Command* getCommand() { return 0; }
     virtual Control* getControl() { return 0; }
@@ -53,6 +53,8 @@
     virtual const Control* getControl() const {
         return const_cast<Action*>(this)->getControl();
     }
+    static const uint8_t SIZE=0;
+    static const uint8_t PACK=2;
 };
 
 struct CommandVisitor;

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=644308&r1=644307&r2=644308&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/tests/serialize.cpp (original)
+++ incubator/qpid/trunk/qpid/cpp/src/tests/serialize.cpp Thu Apr  3 06:27:07 
2008
@@ -22,6 +22,7 @@
 #include "unit_test.h"
 #include "qpid/amqp_0_10/built_in_types.h"
 #include "qpid/amqp_0_10/Codec.h"
+#include "qpid/amqp_0_10/PackedCodec.h"
 #include "qpid/amqp_0_10/specification.h"
 #include "qpid/amqp_0_10/ControlHolder.h"
 #include "qpid/amqp_0_10/Frame.h"
@@ -170,7 +171,7 @@
     
     BOOST_CHECK_EQUAL(data.size(), Codec::size(h));
 
-    Codec::Decode<string::iterator> decode(data.begin());
+    Codec::Decoder<string::iterator> decode(data.begin());
     Control::Holder h2;
     decode(h2);
 
@@ -224,6 +225,17 @@
     BOOST_CHECK_EQUAL(std::string(f2.begin(), f2.end()),
                       std::string(d2, d2+sizeof(d2)));
     
+}
+
+BOOST_AUTO_TEST_CASE(testPackedCodec) {
+    int i=-1, j=-1, k=-1, l=-1;
+    std::string data;
+    Codec::encode(std::back_inserter(data))(1)(3);
+    PackedCodec::decode(0x5, Codec::decode(data.begin()))(i)(j)(k)(l);
+    BOOST_CHECK_EQUAL(i, 1);
+    BOOST_CHECK_EQUAL(j, 0);
+    BOOST_CHECK_EQUAL(k, 3);
+    BOOST_CHECK_EQUAL(l, 0);
 }
 
 QPID_AUTO_TEST_SUITE_END()


Reply via email to