summaryrefslogtreecommitdiff
path: root/cpp/src/qpid
diff options
context:
space:
mode:
authorAlan Conway <aconway@apache.org>2008-04-16 15:33:51 +0000
committerAlan Conway <aconway@apache.org>2008-04-16 15:33:51 +0000
commit775aa6924e2c432791fafd354751bb068129fe2e (patch)
tree920584acaa99df0a6f8d55e53eefc9b38767e519 /cpp/src/qpid
parent79749f81fab85090506e236f8b625801291659a1 (diff)
downloadqpid-python-775aa6924e2c432791fafd354751bb068129fe2e.tar.gz
Fix encoding for sized structs.
git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@648724 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp/src/qpid')
-rw-r--r--cpp/src/qpid/amqp_0_10/Array.h12
-rw-r--r--cpp/src/qpid/amqp_0_10/Command.h62
-rw-r--r--cpp/src/qpid/amqp_0_10/CommmandPacker.h60
-rw-r--r--cpp/src/qpid/amqp_0_10/Control.h (renamed from cpp/src/qpid/amqp_0_10/complex_types.h)51
-rw-r--r--cpp/src/qpid/amqp_0_10/Header.h2
-rw-r--r--cpp/src/qpid/amqp_0_10/Packer.h42
-rw-r--r--cpp/src/qpid/amqp_0_10/Struct.h60
-rw-r--r--cpp/src/qpid/amqp_0_10/Struct32.cpp6
-rw-r--r--cpp/src/qpid/amqp_0_10/Struct32.h13
-rw-r--r--cpp/src/qpid/amqp_0_10/UnknownStruct.h2
-rw-r--r--cpp/src/qpid/amqp_0_10/built_in_types.h4
-rw-r--r--cpp/src/qpid/framing/SequenceSet.h22
12 files changed, 261 insertions, 75 deletions
diff --git a/cpp/src/qpid/amqp_0_10/Array.h b/cpp/src/qpid/amqp_0_10/Array.h
index 8061a99b43..6e8a419df7 100644
--- a/cpp/src/qpid/amqp_0_10/Array.h
+++ b/cpp/src/qpid/amqp_0_10/Array.h
@@ -35,10 +35,11 @@ namespace amqp_0_10 {
template <class T> class ArrayDomain : public std::vector<T> {
public:
- template <class S> void serialize(S& s) { s.split(*this); s(this->begin(), this->end()); }
+ template <class S> void serialize(S& s) { s.split(*this); }
template <class S> void encode(S& s) const {
s(contentSize())(CodeForType<T>::value)(uint32_t(this->size()));
+ s(this->begin(), this->end());
}
void encode(Codec::Size& s) const { s.raw(0, contentSize() + 4/*size*/); }
@@ -46,12 +47,13 @@ template <class T> class ArrayDomain : public std::vector<T> {
template <class S> void decode(S& s) {
uint32_t size; uint8_t type; uint32_t count;
s(size);
- s.setLimit(size);
+ typename S::ScopedLimit l(s, size);
s(type);
if (type != CodeForType<T>::value)
throw InvalidArgumentException(QPID_MSG("Array domain expected type " << CodeForType<T>::value << " but found " << type));
s(count);
this->resize(count);
+ s(this->begin(), this->end());
}
private:
@@ -76,10 +78,11 @@ template<> class ArrayDomain<UnknownType> : public std::vector<UnknownType> {
public:
ArrayDomain(uint8_t type_=0) : type(type_) {}
- template <class S> void serialize(S& s) { s.split(*this); s(this->begin(), this->end()); }
+ template <class S> void serialize(S& s) { s.split(*this); }
template <class S> void encode(S& s) const {
s(contentSize())(type)(uint32_t(this->size()));
+ s(this->begin(), this->end());
}
void encode(Codec::Size& s) const { s.raw(0, contentSize() + 4/*size*/); }
@@ -87,10 +90,11 @@ template<> class ArrayDomain<UnknownType> : public std::vector<UnknownType> {
template <class S> void decode(S& s) {
uint32_t size; uint32_t count;
s(size);
- s.setLimit(size);
+ typename S::ScopedLimit l(s, size);
s(type)(count);
this->clear();
this->resize(count, UnknownType(type));
+ s(this->begin(), this->end());
}
uint8_t getType() const { return type; }
diff --git a/cpp/src/qpid/amqp_0_10/Command.h b/cpp/src/qpid/amqp_0_10/Command.h
new file mode 100644
index 0000000000..0fe023e520
--- /dev/null
+++ b/cpp/src/qpid/amqp_0_10/Command.h
@@ -0,0 +1,62 @@
+#ifndef QPID_AMQP_0_10_COMMAND_H
+#define QPID_AMQP_0_10_COMMAND_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 "Control.h"
+#include "qpid/amqp_0_10/structs.h"
+
+namespace qpid {
+namespace amqp_0_10 {
+
+struct CommandVisitor;
+struct ConstCommandVisitor;
+struct CommandHolder;
+struct Command
+ : public Action,
+ public Visitable<CommandVisitor, ConstCommandVisitor, CommandHolder>
+{
+ using Action::getCommand;
+ Command* getCommand() { return this; }
+ uint8_t getCode() const;
+ uint8_t getClassCode() const;
+ const char* getName() const;
+ const char* getClassName() const;
+
+ session::Header sessionHeader;
+};
+
+std::ostream& operator<<(std::ostream&, const Command&);
+
+template <class T>
+struct CommandPacker : Packer<T> {
+ CommandPacker(T& t) : Packer<T>(t) {}
+
+ template <class S> void serialize(S& s) {
+ s(this->data.sessionHeader);
+ Packer<T>::serialize(s);
+ }
+};
+
+}} // namespace qpid::amqp_0_10
+
+#endif /*!QPID_AMQP_0_10_COMMAND_H*/
diff --git a/cpp/src/qpid/amqp_0_10/CommmandPacker.h b/cpp/src/qpid/amqp_0_10/CommmandPacker.h
new file mode 100644
index 0000000000..51ebfe8186
--- /dev/null
+++ b/cpp/src/qpid/amqp_0_10/CommmandPacker.h
@@ -0,0 +1,60 @@
+#ifndef QPID_AMQP_0_10_COMMMANDPACKER_H
+#define QPID_AMQP_0_10_COMMMANDPACKER_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/structs.h"
+
+namespace qpid {
+namespace amqp_0_10 {
+
+/**
+ * Packer for commands - serialize session.header before pack bits.
+ */
+template <class T>
+class CommmandPacker : public Packer<T>
+{
+ public:
+ CommmandPacker(T& t) : Packer<T>(t) {}
+ template <class S> void serialize(S& s) { s.split(*this); }
+
+ template <class S> void encode(S& s) const {
+ s.sessionHeader(
+ Packer<T>::encode(s);
+ }
+
+ template <class S> void decode(S& s) {
+ Bits bits;
+ s.littleEnd(bits);
+ PackedDecoder<S, Bits> decode(s, bits);
+ data.serialize(decode);
+ }
+
+
+ protected:
+ T& data;
+
+
+};
+}} // namespace qpid::amqp_0_10
+
+#endif /*!QPID_AMQP_0_10_COMMMANDPACKER_H*/
diff --git a/cpp/src/qpid/amqp_0_10/complex_types.h b/cpp/src/qpid/amqp_0_10/Control.h
index 5d327cc46e..226f6f92a6 100644
--- a/cpp/src/qpid/amqp_0_10/complex_types.h
+++ b/cpp/src/qpid/amqp_0_10/Control.h
@@ -1,5 +1,5 @@
-#ifndef QPID_AMQP_0_10_COMPLEX_TYPES_H
-#define QPID_AMQP_0_10_COMPLEX_TYPES_H
+#ifndef QPID_AMQP_0_10_CONTROL_H
+#define QPID_AMQP_0_10_CONTROL_H
/*
*
@@ -22,24 +22,11 @@
*
*/
-#include "built_in_types.h"
-#include <iosfwd>
+#include "Struct.h"
namespace qpid {
namespace amqp_0_10 {
-// Base classes for complex types.
-
-template <class V, class CV, class H> struct Visitable {
- typedef V Visitor;
- typedef CV ConstVisitor;
- typedef H Holder;
-
- virtual ~Visitable() {}
- virtual void accept(Visitor&) = 0;
- virtual void accept(ConstVisitor&) const = 0;
-};
-
struct Command;
struct Control;
@@ -58,22 +45,6 @@ struct Action { // Base for commands & controls
static const uint8_t PACK=2;
};
-struct CommandVisitor;
-struct ConstCommandVisitor;
-struct CommandHolder;
-struct Command
- : public Action,
- public Visitable<CommandVisitor, ConstCommandVisitor, CommandHolder>
-{
- using Action::getCommand;
- Command* getCommand() { return this; }
- uint8_t getCode() const;
- uint8_t getClassCode() const;
- const char* getName() const;
- const char* getClassName() const;
-};
-std::ostream& operator<<(std::ostream&, const Command&);
-
struct ControlVisitor;
struct ConstControlVisitor;
struct ControlHolder;
@@ -90,24 +61,10 @@ struct Control
};
std::ostream& operator<<(std::ostream&, const Control&);
-// Note: only coded structs inherit from Struct.
-struct StructVisitor;
-struct ConstStructVisitor;
-struct StructHolder;
-struct Struct
- : public Visitable<StructVisitor, ConstStructVisitor, StructHolder>
-{
- uint8_t getCode() const;
- uint8_t getPack() const;
- uint8_t getSize() const;
- uint8_t getClassCode() const;
-};
-std::ostream& operator<<(std::ostream&, const Struct&);
-
template <SegmentType E> struct ActionType;
template <> struct ActionType<CONTROL> { typedef Control type; };
template <> struct ActionType<COMMAND> { typedef Command type; };
}} // namespace qpid::amqp_0_10
-#endif /*!QPID_AMQP_0_10_COMPLEX_TYPES_H*/
+#endif /*!QPID_AMQP_0_10_CONTROL_H*/
diff --git a/cpp/src/qpid/amqp_0_10/Header.h b/cpp/src/qpid/amqp_0_10/Header.h
index b3498a1c8c..0ce6ad9135 100644
--- a/cpp/src/qpid/amqp_0_10/Header.h
+++ b/cpp/src/qpid/amqp_0_10/Header.h
@@ -32,7 +32,7 @@ namespace amqp_0_10 {
class Header : public std::vector<Struct32> {
public:
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);
diff --git a/cpp/src/qpid/amqp_0_10/Packer.h b/cpp/src/qpid/amqp_0_10/Packer.h
index 90d72408b5..c38e3a7efa 100644
--- a/cpp/src/qpid/amqp_0_10/Packer.h
+++ b/cpp/src/qpid/amqp_0_10/Packer.h
@@ -123,10 +123,10 @@ class PackedDecoder {
};
/** Metafunction to compute type to contain pack bits. */
-template <int PackBytes> struct PackBitsType;
-template <> struct PackBitsType<1> { typedef uint8_t type; };
-template <> struct PackBitsType<2> { typedef uint16_t type; };
-template <> struct PackBitsType<4> { typedef uint32_t type; };
+template <int Bytes> struct UintOfSize;
+template <> struct UintOfSize<1> { typedef uint8_t type; };
+template <> struct UintOfSize<2> { typedef uint16_t type; };
+template <> struct UintOfSize<4> { typedef uint32_t type; };
/**
* Helper to serialize packed structs.
@@ -134,7 +134,7 @@ template <> struct PackBitsType<4> { typedef uint32_t type; };
template <class T> class Packer
{
public:
- typedef typename PackBitsType<T::PACK>::type Bits;
+ typedef typename UintOfSize<T::PACK>::type Bits;
Packer(T& t) : data(t) {}
@@ -154,10 +154,40 @@ template <class T> class Packer
}
- private:
+ protected:
T& data;
};
+template <class T, uint8_t=T::SIZE> struct SizedPacker : public Packer<T> {
+ typedef typename UintOfSize<T::SIZE>::type Size;
+
+ SizedPacker(T& t) : Packer<T>(t) {}
+
+ template <class S> void serialize(S& s) {
+ s.split(*this);
+ }
+
+ template <class S> void encode(S& s) const {
+ Codec::Size sizer;
+ this->data.serialize(sizer);
+ Size size=size_t(sizer)+T::PACK; // Size with pack bits.
+ s(size);
+ Packer<T>::encode(s);
+ }
+
+ template <class S> void decode(S& s) {
+ Size size;
+ s(size);
+ typename S::ScopedLimit l(s, size);
+ Packer<T>::decode(s);
+ }
+
+};
+
+template <class T> struct SizedPacker<T,0> : public Packer<T> {
+ SizedPacker(T& t) : Packer<T>(t) {}
+};
+
}} // namespace qpid::amqp_0_10
diff --git a/cpp/src/qpid/amqp_0_10/Struct.h b/cpp/src/qpid/amqp_0_10/Struct.h
new file mode 100644
index 0000000000..c0cea09c60
--- /dev/null
+++ b/cpp/src/qpid/amqp_0_10/Struct.h
@@ -0,0 +1,60 @@
+#ifndef QPID_AMQP_0_10_STRUCT_H
+#define QPID_AMQP_0_10_STRUCT_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 "built_in_types.h"
+#include <iosfwd>
+
+namespace qpid {
+namespace amqp_0_10 {
+
+// Base classes for complex types.
+
+template <class V, class CV, class H> struct Visitable {
+ typedef V Visitor;
+ typedef CV ConstVisitor;
+ typedef H Holder;
+
+ virtual ~Visitable() {}
+ virtual void accept(Visitor&) = 0;
+ virtual void accept(ConstVisitor&) const = 0;
+};
+
+
+// Note: only coded structs inherit from Struct.
+struct StructVisitor;
+struct ConstStructVisitor;
+struct StructHolder;
+struct Struct
+ : public Visitable<StructVisitor, ConstStructVisitor, StructHolder>
+{
+ uint8_t getCode() const;
+ uint8_t getPack() const;
+ uint8_t getSize() const;
+ uint8_t getClassCode() const;
+};
+std::ostream& operator<<(std::ostream&, const Struct&);
+
+}} // namespace qpid::amqp_0_10
+
+#endif /*!QPID_AMQP_0_10_STRUCT_H*/
diff --git a/cpp/src/qpid/amqp_0_10/Struct32.cpp b/cpp/src/qpid/amqp_0_10/Struct32.cpp
index b36b118db3..541f02bcc4 100644
--- a/cpp/src/qpid/amqp_0_10/Struct32.cpp
+++ b/cpp/src/qpid/amqp_0_10/Struct32.cpp
@@ -23,6 +23,12 @@
namespace qpid {
namespace amqp_0_10 {
+Struct32::Struct32() {
+ // FIXME aconway 2008-04-16: this is only here to force a valid
+ // default-constructed Struct32 for serialize tests, clean up.
+ *this = in_place<message::MessageResumeResult>();
+}
+
std::ostream& operator<<(std::ostream& o, const Struct32& s) {
return o << static_cast<const StructHolder&>(s);
}
diff --git a/cpp/src/qpid/amqp_0_10/Struct32.h b/cpp/src/qpid/amqp_0_10/Struct32.h
index 1f0c116f91..2ed73e0b4c 100644
--- a/cpp/src/qpid/amqp_0_10/Struct32.h
+++ b/cpp/src/qpid/amqp_0_10/Struct32.h
@@ -30,23 +30,24 @@ namespace amqp_0_10 {
class Struct32 : public StructHolder
{
public:
- Struct32() {}
+ 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 serialize(S& s) { s.split(*this); }
+
+ using StructHolder::operator=;
template <class S> void encode(S& s) const {
s(contentSize());
+ const_cast<Struct32*>(this)->StructHolder::serialize(s);
}
template <class S> void decode(S& s) {
uint32_t contentSz;
s(contentSz);
- s.setLimit(contentSz);
+ typename S::ScopedLimit l(s, contentSz);
+ StructHolder::serialize(s);
}
private:
diff --git a/cpp/src/qpid/amqp_0_10/UnknownStruct.h b/cpp/src/qpid/amqp_0_10/UnknownStruct.h
index 99ba170328..1c66d8e6af 100644
--- a/cpp/src/qpid/amqp_0_10/UnknownStruct.h
+++ b/cpp/src/qpid/amqp_0_10/UnknownStruct.h
@@ -21,7 +21,7 @@
* under the License.
*
*/
-#include "qpid/amqp_0_10/complex_types.h"
+#include "qpid/amqp_0_10/Struct.h"
#include <string>
namespace qpid {
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 ddd31936fa..157696361d 100644
--- a/cpp/src/qpid/amqp_0_10/built_in_types.h
+++ b/cpp/src/qpid/amqp_0_10/built_in_types.h
@@ -23,6 +23,7 @@
#include "qpid/Serializer.h"
#include "qpid/framing/SequenceNumber.h"
+#include "qpid/framing/SequenceSet.h"
#include "qpid/framing/Uuid.h"
#include "qpid/sys/Time.h"
#include "Decimal.h"
@@ -135,6 +136,8 @@ typedef SerializableString<Uint16, Uint16> Str16Utf16;
typedef SerializableString<Uint8, Uint32> Vbin32;
+typedef framing::SequenceSet SequenceSet;
+
// Forward declare class types.
class Map;
class Struct32;
@@ -145,7 +148,6 @@ typedef ArrayDomain<UnknownType> Array;
// FIXME aconway 2008-04-08: TODO
struct ByteRanges { template <class S> void serialize(S&) {} };
-struct SequenceSet { template <class S> void serialize(S&) {} };
struct List { template <class S> void serialize(S&) {} };
// FIXME aconway 2008-03-10: dummy ostream operators
diff --git a/cpp/src/qpid/framing/SequenceSet.h b/cpp/src/qpid/framing/SequenceSet.h
index 2f34cb5cba..226062f35d 100644
--- a/cpp/src/qpid/framing/SequenceSet.h
+++ b/cpp/src/qpid/framing/SequenceSet.h
@@ -21,35 +21,35 @@
#ifndef _framing_SequenceSet_h
#define _framing_SequenceSet_h
-#include <ostream>
-#include <list>
#include "amqp_types.h"
#include "Buffer.h"
#include "SequenceNumber.h"
#include "qpid/framing/reply_exceptions.h"
+#include <ostream>
+#include <list>
namespace qpid {
namespace framing {
-class SequenceSet
-{
- struct Range
- {
+class SequenceSet {
+ struct Range {
SequenceNumber start;
SequenceNumber end;
- Range(SequenceNumber s, SequenceNumber e);
+ Range(SequenceNumber s=0, SequenceNumber e=0);
bool contains(SequenceNumber i) const;
bool intersects(const Range& r) const;
bool merge(const Range& r);
bool mergeable(const SequenceNumber& r) const;
void encode(Buffer& buffer) const;
+
+ template <class S> void serialize(S& s) { s(start)(end); }
};
typedef std::list<Range> Ranges;
Ranges ranges;
-public:
+ public:
SequenceSet() {}
SequenceSet(const SequenceNumber& s) { add(s); }
@@ -76,7 +76,11 @@ public:
}
}
- friend std::ostream& operator<<(std::ostream&, const SequenceSet&);
+ template <class S> void serialize(S& s) { s.split(*this); s(ranges.begin(), ranges.end()); }
+ template <class S> void encode(S& s) const { s(uint16_t(ranges.size()*sizeof(Range))); }
+ template <class S> void decode(S& s) { uint16_t sz; s(sz); ranges.resize(sz/sizeof(Range)); }
+
+ friend std::ostream& operator<<(std::ostream&, const SequenceSet&);
};