diff options
| author | Alan Conway <aconway@apache.org> | 2008-04-16 15:33:51 +0000 |
|---|---|---|
| committer | Alan Conway <aconway@apache.org> | 2008-04-16 15:33:51 +0000 |
| commit | 775aa6924e2c432791fafd354751bb068129fe2e (patch) | |
| tree | 920584acaa99df0a6f8d55e53eefc9b38767e519 /cpp/src/qpid | |
| parent | 79749f81fab85090506e236f8b625801291659a1 (diff) | |
| download | qpid-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.h | 12 | ||||
| -rw-r--r-- | cpp/src/qpid/amqp_0_10/Command.h | 62 | ||||
| -rw-r--r-- | cpp/src/qpid/amqp_0_10/CommmandPacker.h | 60 | ||||
| -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.h | 2 | ||||
| -rw-r--r-- | cpp/src/qpid/amqp_0_10/Packer.h | 42 | ||||
| -rw-r--r-- | cpp/src/qpid/amqp_0_10/Struct.h | 60 | ||||
| -rw-r--r-- | cpp/src/qpid/amqp_0_10/Struct32.cpp | 6 | ||||
| -rw-r--r-- | cpp/src/qpid/amqp_0_10/Struct32.h | 13 | ||||
| -rw-r--r-- | cpp/src/qpid/amqp_0_10/UnknownStruct.h | 2 | ||||
| -rw-r--r-- | cpp/src/qpid/amqp_0_10/built_in_types.h | 4 | ||||
| -rw-r--r-- | cpp/src/qpid/framing/SequenceSet.h | 22 |
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&); }; |
