summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
authorAlan Conway <aconway@apache.org>2008-04-15 18:23:55 +0000
committerAlan Conway <aconway@apache.org>2008-04-15 18:23:55 +0000
commit04f90cff6570c8f035eaa2a86fa31ebd1caf3f0f (patch)
tree4567305f8974177a74655738a694ff2bc167bc59 /cpp/src
parent2a0efe8231595bc6bb891b525427297ce446c20a (diff)
downloadqpid-python-04f90cff6570c8f035eaa2a86fa31ebd1caf3f0f.tar.gz
Correct Struct32 encoding: size/code/data.
Proper re-encoding for unknown struct codes. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@648362 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp/src')
-rw-r--r--cpp/src/qpid/amqp_0_10/Struct32.h60
-rw-r--r--cpp/src/qpid/amqp_0_10/UnknownStruct.cpp2
-rw-r--r--cpp/src/qpid/amqp_0_10/UnknownStruct.h16
-rw-r--r--cpp/src/qpid/amqp_0_10/built_in_types.h1
-rw-r--r--cpp/src/qpid/amqp_0_10/complex_types.cpp4
-rw-r--r--cpp/src/qpid/amqp_0_10/complex_types.h4
-rw-r--r--cpp/src/tests/amqp_0_10/serialize.cpp26
7 files changed, 95 insertions, 18 deletions
diff --git a/cpp/src/qpid/amqp_0_10/Struct32.h b/cpp/src/qpid/amqp_0_10/Struct32.h
new file mode 100644
index 0000000000..662518efb8
--- /dev/null
+++ b/cpp/src/qpid/amqp_0_10/Struct32.h
@@ -0,0 +1,60 @@
+#ifndef QPID_AMQP_0_10_STRUCT32_H
+#define QPID_AMQP_0_10_STRUCT32_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/StructHolder.h"
+
+namespace qpid {
+namespace amqp_0_10 {
+
+class Struct32 : public StructHolder
+{
+ public:
+ Struct32() {}
+
+ template <class T> explicit Struct32(const T& t) : StructHolder(t) {}
+
+ template <class S> void serialize(S& s) {
+ s.split(*this);
+ StructHolder::serialize(s);
+ }
+
+ template <class S> void encode(S& s) const {
+ s(contentSize());
+ }
+
+ template <class S> void decode(S& s) {
+ uint32_t contentSz;
+ s(contentSz);
+ s.setLimit(contentSz);
+ }
+
+ private:
+ uint32_t contentSize() const {
+ return Codec::size(static_cast<const StructHolder&>(*this));
+ }
+
+};
+}} // namespace qpid::amqp_0_10
+
+#endif /*!QPID_AMQP_0_10_STRUCT32_H*/
diff --git a/cpp/src/qpid/amqp_0_10/UnknownStruct.cpp b/cpp/src/qpid/amqp_0_10/UnknownStruct.cpp
index 023e9d08b4..35445054c9 100644
--- a/cpp/src/qpid/amqp_0_10/UnknownStruct.cpp
+++ b/cpp/src/qpid/amqp_0_10/UnknownStruct.cpp
@@ -28,7 +28,7 @@ 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 << "]";
+ return o << "UnknownStruct[class=" << u.getClassCode() << " code=" << u.getCode() << "]";
}
}} // 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
index d4fc77159b..99ba170328 100644
--- a/cpp/src/qpid/amqp_0_10/UnknownStruct.h
+++ b/cpp/src/qpid/amqp_0_10/UnknownStruct.h
@@ -22,18 +22,30 @@
*
*/
#include "qpid/amqp_0_10/complex_types.h"
+#include <string>
namespace qpid {
namespace amqp_0_10 {
-struct UnknownStruct : public Struct, public Vbin32 {
+class UnknownStruct : public Struct {
+ public:
static const uint8_t SIZE=4;
static const uint8_t PACK=2;
-
+
+ template <class S> void serialize(S& s) { s.split(*this); s(data.begin(), data.end()); }
+ template <class S> void encode(S&) const { }
+ template <class S> void decode(S& s) { data.resize(s.bytesRemaining()); }
+
UnknownStruct(uint8_t cc=0, uint8_t c=0) : classCode(cc), code(c) {}
void accept(Visitor&);
void accept(ConstVisitor&) const;
+
+ uint8_t getClassCode() const { return classCode; }
+ uint8_t getCode() const { return code; }
+
+ private:
uint8_t classCode, code;
+ std::string data;
};
std::ostream& operator<<(std::ostream&, const UnknownStruct&);
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 f2ada40bba..ddd31936fa 100644
--- a/cpp/src/qpid/amqp_0_10/built_in_types.h
+++ b/cpp/src/qpid/amqp_0_10/built_in_types.h
@@ -138,6 +138,7 @@ typedef SerializableString<Uint8, Uint32> Vbin32;
// Forward declare class types.
class Map;
class Struct32;
+class List;
class UnknownType;
template <class T> struct ArrayDomain;
typedef ArrayDomain<UnknownType> Array;
diff --git a/cpp/src/qpid/amqp_0_10/complex_types.cpp b/cpp/src/qpid/amqp_0_10/complex_types.cpp
index b2975f56d1..656d363ba6 100644
--- a/cpp/src/qpid/amqp_0_10/complex_types.cpp
+++ b/cpp/src/qpid/amqp_0_10/complex_types.cpp
@@ -56,12 +56,12 @@ 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; }
+ uint8_t operator()(const UnknownStruct& u) const { return u.getCode(); }
};
struct GetStructClassCode : public GetClassCode {
using GetClassCode::operator();
- uint8_t operator()(const UnknownStruct& u) const { return u.classCode; }
+ uint8_t operator()(const UnknownStruct& u) const { return u.getClassCode(); }
};
uint8_t Struct::getCode() const { return apply(GetStructCode(), *this); }
diff --git a/cpp/src/qpid/amqp_0_10/complex_types.h b/cpp/src/qpid/amqp_0_10/complex_types.h
index 46d2fa9491..5d327cc46e 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 Struct32;
+struct StructHolder;
struct Struct
- : public Visitable<StructVisitor, ConstStructVisitor, Struct32>
+ : public Visitable<StructVisitor, ConstStructVisitor, StructHolder>
{
uint8_t getCode() const;
uint8_t getPack() const;
diff --git a/cpp/src/tests/amqp_0_10/serialize.cpp b/cpp/src/tests/amqp_0_10/serialize.cpp
index f533590622..1c569e4ae8 100644
--- a/cpp/src/tests/amqp_0_10/serialize.cpp
+++ b/cpp/src/tests/amqp_0_10/serialize.cpp
@@ -221,10 +221,10 @@ BOOST_AUTO_TEST_CASE(testStruct32) {
string data;
Codec::encode(back_inserter(data))(s);
-// uint32_t structSize; // Starts with size
-// Codec::decode(data.begin())(structSize);
-// BOOST_CHECK_EQUAL(structSize, Codec::size(dp) + 4); // code+pack
-// BOOST_CHECK_EQUAL(structSize, data.size()-4);
+ uint32_t structSize; // Starts with size
+ Codec::decode(data.begin())(structSize);
+ BOOST_CHECK_EQUAL(structSize, Codec::size(dp) + 2); // +2 for code
+ BOOST_CHECK_EQUAL(structSize, data.size()-4); // encoded body
BOOST_CHECK_EQUAL(data.size(), Codec::size(s));
Struct32 s2;
@@ -233,15 +233,19 @@ BOOST_AUTO_TEST_CASE(testStruct32) {
BOOST_REQUIRE(dp2);
BOOST_CHECK_EQUAL(dp2->priority, message::MEDIUM);
BOOST_CHECK_EQUAL(dp2->routingKey, "foo");
+}
+BOOST_AUTO_TEST_CASE(testStruct32Unknown) {
// Verify we can recode an unknown struct unchanged.
-// data.clear();
-// Codec::encode(back_inserter(data))(uint32_t(10));
-// data.append(10, 'X');
-// Codec::decode(data.begin())(s2);
-// string data2;
-// Codec::decode(back_inserter(data2));
- // BOOST_CHECK_EQUAL(data, data2);
+ Struct32 s;
+ string data;
+ Codec::encode(back_inserter(data))(uint32_t(10));
+ data.append(10, 'X');
+ Codec::decode(data.begin())(s);
+ string data2;
+ Codec::encode(back_inserter(data2))(s);
+ BOOST_CHECK_EQUAL(data.size(), data2.size());
+ BOOST_CHECK_EQUAL(data, data2);
}
struct DummyPacked {