diff options
author | Rafael H. Schloming <rhs@apache.org> | 2009-12-26 12:42:57 +0000 |
---|---|---|
committer | Rafael H. Schloming <rhs@apache.org> | 2009-12-26 12:42:57 +0000 |
commit | 248f1fe188fe2307b9dcf2c87a83b653eaa1920c (patch) | |
tree | d5d0959a70218946ff72e107a6c106e32479a398 /cpp/src/qpid/framing/AMQFrame.cpp | |
parent | 3c83a0e3ec7cf4dc23e83a340b25f5fc1676f937 (diff) | |
download | qpid-python-248f1fe188fe2307b9dcf2c87a83b653eaa1920c.tar.gz |
synchronized with trunk except for ruby dir
git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/qpid.rnr@893970 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp/src/qpid/framing/AMQFrame.cpp')
-rw-r--r-- | cpp/src/qpid/framing/AMQFrame.cpp | 80 |
1 files changed, 68 insertions, 12 deletions
diff --git a/cpp/src/qpid/framing/AMQFrame.cpp b/cpp/src/qpid/framing/AMQFrame.cpp index c1fc647b52..5c5920d786 100644 --- a/cpp/src/qpid/framing/AMQFrame.cpp +++ b/cpp/src/qpid/framing/AMQFrame.cpp @@ -18,33 +18,66 @@ * under the License. * */ -#include "AMQFrame.h" +#include "qpid/framing/AMQFrame.h" -#include "qpid/framing/variant.h" #include "qpid/framing/AMQMethodBody.h" #include "qpid/framing/reply_exceptions.h" - +#include "qpid/framing/BodyFactory.h" +#include "qpid/framing/MethodBodyFactory.h" #include <boost/format.hpp> - #include <iostream> namespace qpid { namespace framing { +void AMQFrame::init() { + bof = eof = bos = eos = true; + subchannel=0; + channel=0; + encodedSizeCache = 0; +} + +AMQFrame::AMQFrame(const boost::intrusive_ptr<AMQBody>& b) : body(b) { init(); } + +AMQFrame::AMQFrame(const AMQBody& b) : body(b.clone()) { init(); } + AMQFrame::~AMQFrame() {} -void AMQFrame::setBody(const AMQBody& b) { body = new BodyHolder(b); } +AMQBody* AMQFrame::getBody() { + // Non-const AMQBody* may be used to modify the body. + encodedSizeCache = 0; + return body.get(); +} + +const AMQBody* AMQFrame::getBody() const { + return body.get(); +} -void AMQFrame::setMethod(ClassId c, MethodId m) { body = new BodyHolder(c,m); } +void AMQFrame::setMethod(ClassId c, MethodId m) { + encodedSizeCache = 0; + body = MethodBodyFactory::create(c,m); +} -uint32_t AMQFrame::size() const { - return frameOverhead() + body->size(); +uint32_t AMQFrame::encodedSize() const { + if (!encodedSizeCache) { + encodedSizeCache = frameOverhead() + body->encodedSize(); + if (body->getMethod()) + encodedSizeCache += sizeof(ClassId)+sizeof(MethodId); + } + return encodedSizeCache; } uint32_t AMQFrame::frameOverhead() { return 12 /*frame header*/; } +uint16_t AMQFrame::DECODE_SIZE_MIN=4; + +uint16_t AMQFrame::decodeSize(char* data) { + Buffer buf(data+2, DECODE_SIZE_MIN); + return buf.getShort(); +} + void AMQFrame::encode(Buffer& buffer) const { //set track first (controls on track 0, everything else on 1): @@ -53,20 +86,27 @@ void AMQFrame::encode(Buffer& buffer) const uint8_t flags = (bof ? 0x08 : 0) | (eof ? 0x04 : 0) | (bos ? 0x02 : 0) | (eos ? 0x01 : 0); buffer.putOctet(flags); buffer.putOctet(getBody()->type()); - buffer.putShort(size()); + buffer.putShort(encodedSize()); buffer.putOctet(0); buffer.putOctet(0x0f & track); buffer.putShort(channel); buffer.putLong(0); + const AMQMethodBody* method=getMethod(); + if (method) { + buffer.putOctet(method->amqpClassId()); + buffer.putOctet(method->amqpMethodId()); + } body->encode(buffer); } bool AMQFrame::decode(Buffer& buffer) -{ +{ if(buffer.available() < frameOverhead()) return false; buffer.record(); + encodedSizeCache = 0; + uint32_t start = buffer.getPosition(); uint8_t flags = buffer.getOctet(); uint8_t framing_version = (flags & 0xc0) >> 6; if (framing_version != 0) @@ -98,8 +138,24 @@ bool AMQFrame::decode(Buffer& buffer) buffer.restore(); return false; } - body = new BodyHolder(); - body->decode(type,buffer, body_size); + + switch(type) + { + case 0://CONTROL + case METHOD_BODY: { + ClassId c = buffer.getOctet(); + MethodId m = buffer.getOctet(); + body = MethodBodyFactory::create(c, m); + break; + } + case HEADER_BODY: body = BodyFactory::create<AMQHeaderBody>(); break; + case CONTENT_BODY: body = BodyFactory::create<AMQContentBody>(); break; + case HEARTBEAT_BODY: body = BodyFactory::create<AMQHeartbeatBody>(); break; + default: + throw IllegalArgumentException(QPID_MSG("Invalid frame type " << type)); + } + body->decode(buffer, body_size); + encodedSizeCache = buffer.getPosition() - start; return true; } |