summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
authorAlan Conway <aconway@apache.org>2008-04-15 01:58:05 +0000
committerAlan Conway <aconway@apache.org>2008-04-15 01:58:05 +0000
commit4c49c328cbf78711341fd1b73935c2d2021d5cf3 (patch)
treebf486ace4d214f95ef61d52ea0b5d2519f5044e1 /cpp/src
parent8543f48f658b001f063112ea4472f57d9068ed89 (diff)
downloadqpid-python-4c49c328cbf78711341fd1b73935c2d2021d5cf3.tar.gz
Struct32 encoding
git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@648095 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp/src')
-rw-r--r--cpp/src/Makefile.am3
-rw-r--r--cpp/src/qpid/Serializer.h2
-rw-r--r--cpp/src/qpid/amqp_0_10/Header.cpp (renamed from cpp/src/qpid/amqp_0_10/Frame.cpp)10
-rw-r--r--cpp/src/qpid/amqp_0_10/Header.h25
-rw-r--r--cpp/src/qpid/amqp_0_10/Holder.h8
-rw-r--r--cpp/src/qpid/amqp_0_10/Map.cpp4
-rw-r--r--cpp/src/qpid/amqp_0_10/Map.h2
-rw-r--r--cpp/src/qpid/amqp_0_10/Unit.cpp7
-rw-r--r--cpp/src/qpid/amqp_0_10/UnknownStruct.cpp (renamed from cpp/src/qpid/amqp_0_10/all_built_in_types.h)21
-rw-r--r--cpp/src/qpid/amqp_0_10/UnknownStruct.h43
-rw-r--r--cpp/src/qpid/amqp_0_10/built_in_types.h3
-rw-r--r--cpp/src/qpid/amqp_0_10/complex_types.cpp15
-rw-r--r--cpp/src/qpid/amqp_0_10/complex_types.h4
-rw-r--r--cpp/src/tests/amqp_0_10/Map.cpp6
-rw-r--r--cpp/src/tests/amqp_0_10/serialize.cpp22
15 files changed, 140 insertions, 35 deletions
diff --git a/cpp/src/Makefile.am b/cpp/src/Makefile.am
index a31dbdfa9d..f2665a5a1f 100644
--- a/cpp/src/Makefile.am
+++ b/cpp/src/Makefile.am
@@ -112,6 +112,7 @@ libqpidcommon_la_SOURCES = \
qpid/amqp_0_10/Array.cpp \
qpid/amqp_0_10/Body.h \
qpid/amqp_0_10/Header.h \
+ qpid/amqp_0_10/Header.cpp \
qpid/amqp_0_10/FrameHeader.h \
qpid/amqp_0_10/FrameHeader.cpp \
qpid/amqp_0_10/Holder.h \
@@ -125,6 +126,8 @@ libqpidcommon_la_SOURCES = \
qpid/amqp_0_10/Unit.cpp \
qpid/amqp_0_10/UnknownType.h \
qpid/amqp_0_10/UnknownType.cpp \
+ qpid/amqp_0_10/UnknownStruct.h \
+ qpid/amqp_0_10/UnknownStruct.cpp \
qpid/Serializer.h \
qpid/framing/AccumulatedAck.cpp \
qpid/framing/AMQBody.cpp \
diff --git a/cpp/src/qpid/Serializer.h b/cpp/src/qpid/Serializer.h
index fc53097207..a8ded9f5e0 100644
--- a/cpp/src/qpid/Serializer.h
+++ b/cpp/src/qpid/Serializer.h
@@ -105,7 +105,7 @@ template <class Derived> class Serializer {
/** Get the max number of bytes that can be processed under the
* current limit.
*/
- size_t getLimit() const {
+ size_t bytesRemaining() const {
return limit - bytes;
}
/** Set absolute limit. */
diff --git a/cpp/src/qpid/amqp_0_10/Frame.cpp b/cpp/src/qpid/amqp_0_10/Header.cpp
index 1140b6058d..669c960e7f 100644
--- a/cpp/src/qpid/amqp_0_10/Frame.cpp
+++ b/cpp/src/qpid/amqp_0_10/Header.cpp
@@ -18,11 +18,17 @@
* under the License.
*
*/
-#include "Frame.h"
+#include "Header.h"
namespace qpid {
namespace amqp_0_10 {
-bool Frame::match(const Frame& x) {
+std::ostream& operator<<(std::ostream& o, const Header& h) {
+ o << "Header[";
+ std::ostream_iterator<Struct32> i(o, " ");
+ std::copy(h.begin(), h.end(), i);
+ o << "]";
+ return o;
}
+
}} // namespace qpid::amqp_0_10
diff --git a/cpp/src/qpid/amqp_0_10/Header.h b/cpp/src/qpid/amqp_0_10/Header.h
index 44edcb9f3d..b3498a1c8c 100644
--- a/cpp/src/qpid/amqp_0_10/Header.h
+++ b/cpp/src/qpid/amqp_0_10/Header.h
@@ -21,21 +21,32 @@
* under the License.
*
*/
+#include "qpid/amqp_0_10/built_in_types.h"
+#include "qpid/amqp_0_10/Struct32.h"
+#include <vector>
#include <ostream>
namespace qpid {
namespace amqp_0_10 {
-// FIXME aconway 2008-03-27: TODO
-class Header
-{
+class Header : public std::vector<Struct32> {
public:
- template <class S> void serialize(S&) {}
- private:
+ Header() {}
+
+ template <class S> void serialize(S& s) { s.split(*this); }
+ template <class S> void encode(S& s) const { s(this->begin(), this->end()); }
+ template <class S> void decode(S& s);
};
-// FIXME aconway 2008-03-28: TODO
-inline std::ostream& operator<<(std::ostream& o, const Header&) { return o; }
+template <class S> void Header::decode(S& s) {
+ this->clear();
+ while (s.bytesRemaining() > 0) {
+ this->push_back(Struct32());
+ s(this->back());
+ }
+}
+
+std::ostream& operator<<(std::ostream& o, const Header&);
}} // namespace qpid::amqp_0_10
diff --git a/cpp/src/qpid/amqp_0_10/Holder.h b/cpp/src/qpid/amqp_0_10/Holder.h
index 1664afcc8f..3c734d967f 100644
--- a/cpp/src/qpid/amqp_0_10/Holder.h
+++ b/cpp/src/qpid/amqp_0_10/Holder.h
@@ -73,6 +73,14 @@ class Holder : public framing::Blob<Size, BaseHeld> {
apply(s, *this->get());
}
+ template <class T> T* getIf() {
+ return (getClassCode()==T::CLASS_CODE && getCode()==T::CODE) ? static_cast<T*>(this->get()) : 0;
+ }
+
+ template <class T> const T* getIf() const {
+ return (getClassCode()==T::CLASS_CODE && getCode()==T::CODE) ? static_cast<T*>(this->get()) : 0;
+ }
+
private:
struct Assign : public ApplyFunctor<void> {
Holder& holder;
diff --git a/cpp/src/qpid/amqp_0_10/Map.cpp b/cpp/src/qpid/amqp_0_10/Map.cpp
index 2d32466c3f..b517b8baba 100644
--- a/cpp/src/qpid/amqp_0_10/Map.cpp
+++ b/cpp/src/qpid/amqp_0_10/Map.cpp
@@ -18,7 +18,9 @@
* under the License.
*
*/
-#include "all_built_in_types.h"
+#include "Map.h"
+#include "qpid/amqp_0_10/Struct32.h"
+#include "qpid/amqp_0_10/Array.h"
#include <ostream>
namespace qpid {
diff --git a/cpp/src/qpid/amqp_0_10/Map.h b/cpp/src/qpid/amqp_0_10/Map.h
index d63eb0cc4e..c0dcf73930 100644
--- a/cpp/src/qpid/amqp_0_10/Map.h
+++ b/cpp/src/qpid/amqp_0_10/Map.h
@@ -171,7 +171,7 @@ template <class S> void Map::decode(S& s) {
typename S::ScopedLimit l(s, decodedSize); // Make sure we don't overrun.
// FIXME aconway 2008-04-03: replace preview with 0-10:
// for ( ; count > 0; --count) {
- while (s.getLimit() > 0) {
+ while (s.bytesRemaining() > 0) {
key_type k; MapValue v;
s(k)(v);
insert(value_type(k,v));
diff --git a/cpp/src/qpid/amqp_0_10/Unit.cpp b/cpp/src/qpid/amqp_0_10/Unit.cpp
index 1fa6b2e085..75ea1c1b30 100644
--- a/cpp/src/qpid/amqp_0_10/Unit.cpp
+++ b/cpp/src/qpid/amqp_0_10/Unit.cpp
@@ -27,9 +27,10 @@ namespace amqp_0_10 {
void Unit::updateVariant() {
switch (header.getType()) {
case CONTROL: variant=ControlHolder(); break;
- case COMMAND: variant=CommandHolder();
- case HEADER: variant=Header();
- case BODY: variant=Body(header.getDataSize());
+ case COMMAND: variant=CommandHolder(); break;
+ case HEADER: variant=Header(); break;
+ case BODY: variant=Body(header.getDataSize()); break;
+ default: assert(0); // FIXME aconway 2008-04-14: exception?
}
}
diff --git a/cpp/src/qpid/amqp_0_10/all_built_in_types.h b/cpp/src/qpid/amqp_0_10/UnknownStruct.cpp
index 1568465004..023e9d08b4 100644
--- a/cpp/src/qpid/amqp_0_10/all_built_in_types.h
+++ b/cpp/src/qpid/amqp_0_10/UnknownStruct.cpp
@@ -1,6 +1,3 @@
-#ifndef QPID_AMQP_0_10_ALL_BUILT_IN_TYPES_H
-#define QPID_AMQP_0_10_ALL_BUILT_IN_TYPES_H
-
/*
*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -22,10 +19,16 @@
*
*/
-#include "built_in_types.h"
-#include "Map.h"
-#include "Array.h"
-#include "UnknownType.h"
-#include "complex_types.h"
+#include "qpid/amqp_0_10/StructVisitor.h"
+#include "qpid/amqp_0_10/UnknownStruct.h"
+
+namespace qpid {
+namespace amqp_0_10 {
+
+void UnknownStruct::accept(Visitor& v) { v.visit(*this); }
+void UnknownStruct::accept(ConstVisitor& v) const { v.visit(*this); }
+std::ostream& operator<<(std::ostream& o, const UnknownStruct& u) {
+ return o << "UnknownStruct[class=" << u.classCode << " code=" << u.code << "]";
+}
-#endif /*!QPID_AMQP_0_10_ALL_BUILT_IN_TYPES_H*/
+}} // namespace qpid::amqp_0_10
diff --git a/cpp/src/qpid/amqp_0_10/UnknownStruct.h b/cpp/src/qpid/amqp_0_10/UnknownStruct.h
new file mode 100644
index 0000000000..d4fc77159b
--- /dev/null
+++ b/cpp/src/qpid/amqp_0_10/UnknownStruct.h
@@ -0,0 +1,43 @@
+#ifndef QPID_AMQP_0_10_UNKNOWNSTRUCT_H
+#define QPID_AMQP_0_10_UNKNOWNSTRUCT_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 "qpid/amqp_0_10/complex_types.h"
+
+namespace qpid {
+namespace amqp_0_10 {
+
+struct UnknownStruct : public Struct, public Vbin32 {
+ static const uint8_t SIZE=4;
+ static const uint8_t PACK=2;
+
+ UnknownStruct(uint8_t cc=0, uint8_t c=0) : classCode(cc), code(c) {}
+ void accept(Visitor&);
+ void accept(ConstVisitor&) const;
+ uint8_t classCode, code;
+};
+
+std::ostream& operator<<(std::ostream&, const UnknownStruct&);
+
+}} // namespace qpid::amqp_0_10
+
+#endif /*!QPID_AMQP_0_10_UNKNOWNSTRUCT_H*/
diff --git a/cpp/src/qpid/amqp_0_10/built_in_types.h b/cpp/src/qpid/amqp_0_10/built_in_types.h
index dccb6a4785..f2ada40bba 100644
--- a/cpp/src/qpid/amqp_0_10/built_in_types.h
+++ b/cpp/src/qpid/amqp_0_10/built_in_types.h
@@ -137,6 +137,7 @@ typedef SerializableString<Uint8, Uint32> Vbin32;
// Forward declare class types.
class Map;
+class Struct32;
class UnknownType;
template <class T> struct ArrayDomain;
typedef ArrayDomain<UnknownType> Array;
@@ -145,13 +146,11 @@ typedef ArrayDomain<UnknownType> Array;
struct ByteRanges { template <class S> void serialize(S&) {} };
struct SequenceSet { template <class S> void serialize(S&) {} };
struct List { template <class S> void serialize(S&) {} };
-struct Struct32 { template <class S> void serialize(S&) {} };
// FIXME aconway 2008-03-10: dummy ostream operators
inline std::ostream& operator<<(std::ostream& o, const ByteRanges&) { return o; }
inline std::ostream& operator<<(std::ostream& o, const SequenceSet&) { return o; }
inline std::ostream& operator<<(std::ostream& o, const List&) { return o; }
-inline std::ostream& operator<<(std::ostream& o, const Struct32&) { return o; }
enum SegmentType { CONTROL, COMMAND, HEADER, BODY };
diff --git a/cpp/src/qpid/amqp_0_10/complex_types.cpp b/cpp/src/qpid/amqp_0_10/complex_types.cpp
index 78ddfeb026..b2975f56d1 100644
--- a/cpp/src/qpid/amqp_0_10/complex_types.cpp
+++ b/cpp/src/qpid/amqp_0_10/complex_types.cpp
@@ -19,6 +19,7 @@
*
*/
+#include "qpid/amqp_0_10/UnknownStruct.h"
#include "qpid/amqp_0_10/ApplyCommand.h"
#include "qpid/amqp_0_10/ApplyControl.h"
#include "qpid/amqp_0_10/ApplyStruct.h"
@@ -52,11 +53,21 @@ uint8_t Control::getClassCode() const { return apply(GetClassCode(), *this); }
const char* Control::getName() const { return apply(GetName(), *this); }
const char* Control::getClassName() const { return apply(GetClassName(), *this); }
+// Special cases for UnknownStruct
+struct GetStructCode : public GetCode {
+ using GetCode::operator();
+ uint8_t operator()(const UnknownStruct& u) const { return u.code; }
+};
+
+struct GetStructClassCode : public GetClassCode {
+ using GetClassCode::operator();
+ uint8_t operator()(const UnknownStruct& u) const { return u.classCode; }
+};
-uint8_t Struct::getCode() const { return apply(GetCode(), *this); }
+uint8_t Struct::getCode() const { return apply(GetStructCode(), *this); }
+uint8_t Struct::getClassCode() const { return apply(GetStructClassCode(), *this); }
uint8_t Struct::getPack() const { return apply(GetPack(), *this); }
uint8_t Struct::getSize() const { return apply(GetSize(), *this); }
-uint8_t Struct::getClassCode() const { return apply(GetClassCode(), *this); }
struct PrintVisitor {
typedef std::ostream& result_type;
diff --git a/cpp/src/qpid/amqp_0_10/complex_types.h b/cpp/src/qpid/amqp_0_10/complex_types.h
index 5d327cc46e..46d2fa9491 100644
--- a/cpp/src/qpid/amqp_0_10/complex_types.h
+++ b/cpp/src/qpid/amqp_0_10/complex_types.h
@@ -93,9 +93,9 @@ std::ostream& operator<<(std::ostream&, const Control&);
// Note: only coded structs inherit from Struct.
struct StructVisitor;
struct ConstStructVisitor;
-struct StructHolder;
+struct Struct32;
struct Struct
- : public Visitable<StructVisitor, ConstStructVisitor, StructHolder>
+ : public Visitable<StructVisitor, ConstStructVisitor, Struct32>
{
uint8_t getCode() const;
uint8_t getPack() const;
diff --git a/cpp/src/tests/amqp_0_10/Map.cpp b/cpp/src/tests/amqp_0_10/Map.cpp
index dcba6e38c2..dcec1f49f7 100644
--- a/cpp/src/tests/amqp_0_10/Map.cpp
+++ b/cpp/src/tests/amqp_0_10/Map.cpp
@@ -19,8 +19,10 @@
*
*/
#include "unit_test.h"
-#include "qpid/amqp_0_10/all_built_in_types.h"
-//FIXME aconway 2008-04-08: #include "qpid/amqp_0_10/allSegmentTypes.h"
+#include "qpid/amqp_0_10/Map.h"
+#include "qpid/amqp_0_10/Array.h"
+#include "qpid/amqp_0_10/Struct32.h"
+#include "qpid/amqp_0_10/UnknownType.h"
#include "qpid/amqp_0_10/Codec.h"
#include <iostream>
diff --git a/cpp/src/tests/amqp_0_10/serialize.cpp b/cpp/src/tests/amqp_0_10/serialize.cpp
index 8928a9fbc9..f38de33bcc 100644
--- a/cpp/src/tests/amqp_0_10/serialize.cpp
+++ b/cpp/src/tests/amqp_0_10/serialize.cpp
@@ -30,7 +30,7 @@
#include "qpid/amqp_0_10/Codec.h"
#include "qpid/amqp_0_10/specification.h"
#include "qpid/amqp_0_10/ControlHolder.h"
-#include "qpid/amqp_0_10/StructHolder.h"
+#include "qpid/amqp_0_10/Struct32.h"
#include "qpid/amqp_0_10/FrameHeader.h"
#include "qpid/amqp_0_10/Map.h"
#include "qpid/amqp_0_10/Unit.h"
@@ -213,6 +213,22 @@ BOOST_AUTO_TEST_CASE(testControlEncodeDecode) {
BOOST_CHECK_EQUAL(tune.heartbeatMax, 4u);
}
+BOOST_AUTO_TEST_CASE(testStruct32) {
+ message::DeliveryProperties dp;
+ dp.priority=message::MEDIUM;
+ dp.routingKey="foo";
+ Struct32 s(dp);
+ string data;
+ Codec::encode(back_inserter(data))(s);
+ BOOST_CHECK_EQUAL(data.size(), Codec::size(s));
+ Struct32 s2;
+ Codec::decode(data.begin())(s2);
+ message::DeliveryProperties* dp2 = s2.getIf<message::DeliveryProperties>();
+ BOOST_REQUIRE(dp2);
+ BOOST_CHECK_EQUAL(dp2->priority, message::MEDIUM);
+ BOOST_CHECK_EQUAL(dp2->routingKey, "foo");
+}
+
struct DummyPacked {
static const uint8_t PACK=1;
boost::optional<char> i, j;
@@ -319,10 +335,10 @@ BOOST_AUTO_TEST_CASE(testStruct) {
BOOST_CHECK_EQUAL(encodedBits, packBits(dp));
data.clear();
- Struct::Holder h(dp);
+ Struct32 h(dp);
Codec::encode(back_inserter(data))(h);
- Struct::Holder h2;
+ Struct32 h2;
Codec::decode(data.begin())(h2);
BOOST_CHECK_EQUAL(h2.getClassCode(), Uint8(message::DeliveryProperties::CLASS_CODE));
BOOST_CHECK_EQUAL(h2.getCode(), Uint8(message::DeliveryProperties::CODE));