From 248f1fe188fe2307b9dcf2c87a83b653eaa1920c Mon Sep 17 00:00:00 2001 From: "Rafael H. Schloming" Date: Sat, 26 Dec 2009 12:42:57 +0000 Subject: 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 --- cpp/src/qpid/framing/AMQFrame.cpp | 80 +++++++++++++++++++++++++++++++++------ 1 file changed, 68 insertions(+), 12 deletions(-) (limited to 'cpp/src/qpid/framing/AMQFrame.cpp') 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 - #include namespace qpid { namespace framing { +void AMQFrame::init() { + bof = eof = bos = eos = true; + subchannel=0; + channel=0; + encodedSizeCache = 0; +} + +AMQFrame::AMQFrame(const boost::intrusive_ptr& 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(); break; + case CONTENT_BODY: body = BodyFactory::create(); break; + case HEARTBEAT_BODY: body = BodyFactory::create(); break; + default: + throw IllegalArgumentException(QPID_MSG("Invalid frame type " << type)); + } + body->decode(buffer, body_size); + encodedSizeCache = buffer.getPosition() - start; return true; } -- cgit v1.2.1