diff options
| author | Gordon Sim <gsim@apache.org> | 2008-03-03 14:49:06 +0000 |
|---|---|---|
| committer | Gordon Sim <gsim@apache.org> | 2008-03-03 14:49:06 +0000 |
| commit | b4dac41573e33e1a04a2b7b8c9a35f5e72b662bc (patch) | |
| tree | 15e25a2dc7b42f3788f9dccdd7e632dcf8c346d2 /cpp/src/qpid/framing | |
| parent | 928699508993a5ccc59254027773281883d1e973 (diff) | |
| download | qpid-python-b4dac41573e33e1a04a2b7b8c9a35f5e72b662bc.tar.gz | |
A further step to final 0-10 spec.
The extra.xml fragment adds class defs for connection in session that are in line with latest spec but use old schema.
The preview codepath (99-0) remains unaltered.
git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@633108 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp/src/qpid/framing')
| -rw-r--r-- | cpp/src/qpid/framing/AccumulatedAck.cpp | 2 | ||||
| -rw-r--r-- | cpp/src/qpid/framing/BodyHolder.cpp | 1 | ||||
| -rw-r--r-- | cpp/src/qpid/framing/Buffer.cpp | 14 | ||||
| -rw-r--r-- | cpp/src/qpid/framing/Buffer.h | 2 | ||||
| -rw-r--r-- | cpp/src/qpid/framing/SequenceNumber.cpp | 5 | ||||
| -rw-r--r-- | cpp/src/qpid/framing/SequenceNumber.h | 2 | ||||
| -rw-r--r-- | cpp/src/qpid/framing/SequenceSet.cpp | 222 | ||||
| -rw-r--r-- | cpp/src/qpid/framing/SequenceSet.h | 86 | ||||
| -rw-r--r-- | cpp/src/qpid/framing/amqp_types.h | 1 | ||||
| -rw-r--r-- | cpp/src/qpid/framing/amqp_types_full.h | 1 |
10 files changed, 332 insertions, 4 deletions
diff --git a/cpp/src/qpid/framing/AccumulatedAck.cpp b/cpp/src/qpid/framing/AccumulatedAck.cpp index bf53bf0cd6..2d3ecf3f6a 100644 --- a/cpp/src/qpid/framing/AccumulatedAck.cpp +++ b/cpp/src/qpid/framing/AccumulatedAck.cpp @@ -83,7 +83,7 @@ void AccumulatedAck::update(SequenceNumber first, SequenceNumber last){ void AccumulatedAck::consolidate(){} void AccumulatedAck::clear(){ - mark = 0;//not sure that this is valid when wraparound is a possibility + mark = SequenceNumber(0);//not sure that this is valid when wraparound is a possibility ranges.clear(); } diff --git a/cpp/src/qpid/framing/BodyHolder.cpp b/cpp/src/qpid/framing/BodyHolder.cpp index f66f29d36a..de971b5b28 100644 --- a/cpp/src/qpid/framing/BodyHolder.cpp +++ b/cpp/src/qpid/framing/BodyHolder.cpp @@ -48,6 +48,7 @@ void BodyHolder::encode(Buffer& b) const { void BodyHolder::decode(uint8_t type, Buffer& buffer, uint32_t size) { switch(type) { + case 0://CONTROL case METHOD_BODY: { ClassId c = buffer.getOctet(); MethodId m = buffer.getOctet(); diff --git a/cpp/src/qpid/framing/Buffer.cpp b/cpp/src/qpid/framing/Buffer.cpp index c0cd210042..60d67f1b07 100644 --- a/cpp/src/qpid/framing/Buffer.cpp +++ b/cpp/src/qpid/framing/Buffer.cpp @@ -194,6 +194,13 @@ void Buffer::putShortString(const string& s){ position += len; } +void Buffer::putMediumString(const string& s){ + uint16_t len = s.length(); + putShort(len); + s.copy(data + position, len); + position += len; +} + void Buffer::putLongString(const string& s){ uint32_t len = s.length(); putLong(len); @@ -208,6 +215,13 @@ void Buffer::getShortString(string& s){ position += len; } +void Buffer::getMediumString(string& s){ + uint16_t len = getShort(); + checkAvailable(len); + s.assign(data + position, len); + position += len; +} + void Buffer::getLongString(string& s){ uint32_t len = getLong(); checkAvailable(len); diff --git a/cpp/src/qpid/framing/Buffer.h b/cpp/src/qpid/framing/Buffer.h index 9c0d403462..585379b09a 100644 --- a/cpp/src/qpid/framing/Buffer.h +++ b/cpp/src/qpid/framing/Buffer.h @@ -97,8 +97,10 @@ class Buffer void putUInt(uint64_t); void putShortString(const string& s); + void putMediumString(const string& s); void putLongString(const string& s); void getShortString(string& s); + void getMediumString(string& s); void getLongString(string& s); void getBin128(uint8_t* b); diff --git a/cpp/src/qpid/framing/SequenceNumber.cpp b/cpp/src/qpid/framing/SequenceNumber.cpp index 3172246cc2..1b62d296c6 100644 --- a/cpp/src/qpid/framing/SequenceNumber.cpp +++ b/cpp/src/qpid/framing/SequenceNumber.cpp @@ -51,9 +51,10 @@ const SequenceNumber SequenceNumber::operator++(int) return old; } -SequenceNumber SequenceNumber::operator+(uint32_t i) const +SequenceNumber& SequenceNumber::operator--() { - return SequenceNumber(value + i); + value = value - 1; + return *this; } bool SequenceNumber::operator<(const SequenceNumber& other) const diff --git a/cpp/src/qpid/framing/SequenceNumber.h b/cpp/src/qpid/framing/SequenceNumber.h index b2594452d0..0ed591b804 100644 --- a/cpp/src/qpid/framing/SequenceNumber.h +++ b/cpp/src/qpid/framing/SequenceNumber.h @@ -39,7 +39,7 @@ class SequenceNumber SequenceNumber& operator++();//prefix ++ const SequenceNumber operator++(int);//postfix ++ - SequenceNumber operator+(uint32_t) const; + SequenceNumber& operator--();//prefix ++ bool operator==(const SequenceNumber& other) const; bool operator!=(const SequenceNumber& other) const; bool operator<(const SequenceNumber& other) const; diff --git a/cpp/src/qpid/framing/SequenceSet.cpp b/cpp/src/qpid/framing/SequenceSet.cpp new file mode 100644 index 0000000000..e3461e233b --- /dev/null +++ b/cpp/src/qpid/framing/SequenceSet.cpp @@ -0,0 +1,222 @@ +/* + * + * 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 "SequenceSet.h" + +using namespace qpid::framing; +using std::max; +using std::min; + +namespace { +//each range contains 2 numbers, 4 bytes each +uint16_t RANGE_SIZE = 2 * 4; +} + +void SequenceSet::encode(Buffer& buffer) const +{ + buffer.putShort(ranges.size() * RANGE_SIZE); + for (Ranges::const_iterator i = ranges.begin(); i != ranges.end(); i++) { + i->encode(buffer); + } +} + +void SequenceSet::decode(Buffer& buffer) +{ + uint16_t size = buffer.getShort(); + uint16_t count = size / RANGE_SIZE;//number of ranges + if (size % RANGE_SIZE) throw FrameErrorException(QPID_MSG("Invalid size for sequence set: " << size)); + + for (uint16_t i = 0; i < count; i++) { + add(SequenceNumber(buffer.getLong()), SequenceNumber(buffer.getLong())); + } +} + +uint32_t SequenceSet::size() const +{ + return 2 /*size field*/ + (ranges.size() * RANGE_SIZE); +} + +bool SequenceSet::contains(const SequenceNumber& point) const +{ + for (Ranges::const_iterator i = ranges.begin(); i != ranges.end(); i++) { + if (i->contains(point)) return true; + } + return false; +} + +void SequenceSet::add(const SequenceNumber& s) +{ + add(s, s); +} + +void SequenceSet::add(const SequenceNumber& start, const SequenceNumber& end) +{ + if (start > end) { + add(end, start); + } else { + Range r(start, end); + bool merged = false; + Ranges::iterator i = ranges.begin(); + while (i != ranges.end() && !merged && i->start < start) { + if (i->merge(r)) merged = true; + i++; + } + if (!merged) { + ranges.insert(i, r); + } + } +} + +void SequenceSet::add(const SequenceSet& set) +{ + for (Ranges::const_iterator i = set.ranges.begin(); i != set.ranges.end(); i++) { + add(i->start, i->end); + } +} + +void SequenceSet::remove(const SequenceSet& set) +{ + for (Ranges::const_iterator i = set.ranges.begin(); i != set.ranges.end(); i++) { + remove(i->start, i->end); + } +} + +void SequenceSet::remove(const SequenceNumber& start, const SequenceNumber& end) +{ + if (start > end) { + remove(end, start); + } else { + Ranges::iterator i = ranges.begin(); + while (i != ranges.end() && i->start < start) { + if (start <= i->end) { + if (end > i->end) { + //i.e. start is within the range pointed to by i, but end is not + i->end = (uint32_t)start - 1; + } else { + //whole of range to be deleted is contained within that pointed to be i + if (end == i->end) { + //just shrink range pointed to by i + i->end = (uint32_t)start - 1; + } else { + //need to split the range pointed to by i + Range r(i->start, (uint32_t)start - 1); + i->start = end + 1; + ranges.insert(i, r); + } + return;//no need to go any further + } + } + i++; + } + Ranges::iterator j = i; + while (j != ranges.end() && j->end < end) { + j++; + } + if (j->start <= end){ + j->start = end + 1; + } + ranges.erase(i, j); + } +} + +void SequenceSet::remove(const SequenceNumber& s) +{ + for (Ranges::iterator i = ranges.begin(); i != ranges.end() && s >= i->start; i++) { + if (i->start == s) { + if (i->start == i->end) { + ranges.erase(i); + } else { + ++(i->start); + } + } else if (i->end == s) { + --(i->end); + } else if (i->contains(s)) { + //need to split range pointed to by i + Range r(i->start, (uint32_t)s - 1); + i->start = s + 1; + ranges.insert(i, r); + } + } +} + +bool SequenceSet::empty() const +{ + return ranges.empty(); +} + +void SequenceSet::clear() +{ + return ranges.clear(); +} + +bool SequenceSet::Range::contains(SequenceNumber i) const +{ + return i >= start && i <= end; +} + +bool SequenceSet::Range::intersects(const Range& r) const +{ + return r.contains(start) || r.contains(end) || contains(r.start) || contains(r.end); +} + +bool SequenceSet::Range::merge(const Range& r) +{ + if (intersects(r) || mergeable(r.end) || r.mergeable(end)) { + start = min(start, r.start); + end = max(end, r.end); + return true; + } else { + return false; + } +} + +bool SequenceSet::Range::mergeable(const SequenceNumber& s) const +{ + if (contains(s) || start - s == 1) { + return true; + } else { + return false; + } +} + +void SequenceSet::Range::encode(Buffer& buffer) const +{ + buffer.putLong(start); + buffer.putLong(end); +} + +SequenceSet::Range::Range(SequenceNumber s, SequenceNumber e) : start(s), end(e) {} + +namespace qpid{ +namespace framing{ + +std::ostream& operator<<(std::ostream& out, const SequenceSet& set) { + out << "{"; + for (SequenceSet::Ranges::const_iterator i = set.ranges.begin(); i != set.ranges.end(); i++) { + if (i != set.ranges.begin()) out << ", "; + out << i->start.getValue() << "-" << i->end.getValue(); + } + out << "}"; + return out; +} + +} +} diff --git a/cpp/src/qpid/framing/SequenceSet.h b/cpp/src/qpid/framing/SequenceSet.h new file mode 100644 index 0000000000..2f34cb5cba --- /dev/null +++ b/cpp/src/qpid/framing/SequenceSet.h @@ -0,0 +1,86 @@ +/* + * + * 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. + * + */ +#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" + +namespace qpid { +namespace framing { + +class SequenceSet +{ + struct Range + { + SequenceNumber start; + SequenceNumber end; + + Range(SequenceNumber s, SequenceNumber e); + 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; + }; + + typedef std::list<Range> Ranges; + Ranges ranges; + +public: + SequenceSet() {} + SequenceSet(const SequenceNumber& s) { add(s); } + + void encode(Buffer& buffer) const; + void decode(Buffer& buffer); + uint32_t size() const; + + bool contains(const SequenceNumber& s) const; + void add(const SequenceNumber& s); + void add(const SequenceNumber& start, const SequenceNumber& end); + void add(const SequenceSet& set); + void remove(const SequenceNumber& s); + void remove(const SequenceNumber& start, const SequenceNumber& end); + void remove(const SequenceSet& set); + + void clear(); + bool empty() const; + + template <class T> + void for_each(T& t) const + { + for (Ranges::const_iterator i = ranges.begin(); i != ranges.end(); i++) { + t(i->start, i->end); + } + } + + friend std::ostream& operator<<(std::ostream&, const SequenceSet&); +}; + + +}} // namespace qpid::framing + + +#endif diff --git a/cpp/src/qpid/framing/amqp_types.h b/cpp/src/qpid/framing/amqp_types.h index 94442aa357..943970cc56 100644 --- a/cpp/src/qpid/framing/amqp_types.h +++ b/cpp/src/qpid/framing/amqp_types.h @@ -65,6 +65,7 @@ const ChannelId CHANNEL_HIGH_BIT= ChannelId(~CHANNEL_MAX); class FramingContent; class FieldTable; class SequenceNumberSet; +class SequenceSet; class Uuid; }} // namespace qpid::framing diff --git a/cpp/src/qpid/framing/amqp_types_full.h b/cpp/src/qpid/framing/amqp_types_full.h index f1ed44ec05..da7bdc876d 100644 --- a/cpp/src/qpid/framing/amqp_types_full.h +++ b/cpp/src/qpid/framing/amqp_types_full.h @@ -34,6 +34,7 @@ #include "FramingContent.h" #include "FieldTable.h" #include "SequenceNumberSet.h" +#include "SequenceSet.h" #include "Uuid.h" #endif /*!_framing_amqp_types_decl_h*/ |
