summaryrefslogtreecommitdiff
path: root/cpp/src/qpid/framing/AMQFrame.cpp
diff options
context:
space:
mode:
authorRafael H. Schloming <rhs@apache.org>2009-12-26 12:42:57 +0000
committerRafael H. Schloming <rhs@apache.org>2009-12-26 12:42:57 +0000
commit248f1fe188fe2307b9dcf2c87a83b653eaa1920c (patch)
treed5d0959a70218946ff72e107a6c106e32479a398 /cpp/src/qpid/framing/AMQFrame.cpp
parent3c83a0e3ec7cf4dc23e83a340b25f5fc1676f937 (diff)
downloadqpid-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.cpp80
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;
}