From cb070d9813e4232b4ec8409ca555b529ee5cee4b Mon Sep 17 00:00:00 2001 From: Alan Conway Date: Thu, 22 Nov 2007 23:55:39 +0000 Subject: Added framing::BodyHolder: - Uniform holder for all body types, replaces MethodHolder. - Uses in_place constructors to avoid avoid body copy. framing::AMQFrame: - Holds body in heap-allocated intrusive_ptr - Uses in_place constructors to avoid avoid body copy. Removed/downgraded to TODO many redundant FIXME comments. git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@597513 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/src/qpid/framing/AMQFrame.h | 82 ++++++++++++++++------------------------- 1 file changed, 32 insertions(+), 50 deletions(-) (limited to 'cpp/src/qpid/framing/AMQFrame.h') diff --git a/cpp/src/qpid/framing/AMQFrame.h b/cpp/src/qpid/framing/AMQFrame.h index 392b8c0c01..1c65988b3d 100644 --- a/cpp/src/qpid/framing/AMQFrame.h +++ b/cpp/src/qpid/framing/AMQFrame.h @@ -25,46 +25,48 @@ #include "AMQHeaderBody.h" #include "AMQContentBody.h" #include "AMQHeartbeatBody.h" -#include "MethodHolder.h" #include "ProtocolVersion.h" +#include "BodyHolder.h" #include -#include namespace qpid { namespace framing { - + +class BodyHolder; + class AMQFrame : public AMQDataBlock { public: - AMQFrame() : bof(true), eof(true), bos(true), eos(true), subchannel(0), channel(0) {} + AMQFrame(intrusive_ptr b=0) : body(b) { init(); } + AMQFrame(const AMQBody& b) { setBody(b); init(); } + ~AMQFrame(); - /** Construct a frame with a copy of b */ - AMQFrame(ChannelId c, const AMQBody* b) : bof(true), eof(true), bos(true), eos(true), subchannel(0), channel(c) { - setBody(*b); - } - - AMQFrame(ChannelId c, const AMQBody& b) : bof(true), eof(true), bos(true), eos(true), subchannel(0), channel(c) { - setBody(b); + template + AMQFrame(const InPlace& ip, typename EnableInPlace::type* =0) { + init(); setBody(ip); } - - AMQFrame(const AMQBody& b) : bof(true), eof(true), bos(true), eos(true), subchannel(0), channel(0) { - setBody(b); - } - + ChannelId getChannel() const { return channel; } void setChannel(ChannelId c) { channel = c; } - AMQBody* getBody(); - const AMQBody* getBody() const; + intrusive_ptr getHolder() { return body; } + + AMQBody* getBody() { return body ? body->get() : 0; } + const AMQBody* getBody() const { return body ? body->get() : 0; } AMQMethodBody* getMethod() { return getBody()->getMethod(); } const AMQMethodBody* getMethod() const { return getBody()->getMethod(); } - /** Copy a body instance to the frame */ - void setBody(const AMQBody& b) { CopyVisitor cv(*this); b.accept(cv); } + void setBody(const AMQBody& b); + + template + typename EnableInPlace::type setBody(const InPlace& ip) { + body = new BodyHolder(ip); + } + + void setMethod(ClassId c, MethodId m); - /** Convenience template to cast the body to an expected type. */ template T* castBody() { return boost::polymorphic_downcast(getBody()); } @@ -73,8 +75,6 @@ class AMQFrame : public AMQDataBlock return boost::polymorphic_downcast(getBody()); } - bool empty() { return boost::get(&body); } - void encode(Buffer& buffer) const; bool decode(Buffer& buffer); uint32_t size() const; @@ -92,33 +92,15 @@ class AMQFrame : public AMQDataBlock static uint32_t frameOverhead(); private: - struct CopyVisitor : public AMQBodyConstVisitor { - AMQFrame& frame; - CopyVisitor(AMQFrame& f) : frame(f) {} - void visit(const AMQHeaderBody& x) { frame.body=x; } - void visit(const AMQContentBody& x) { frame.body=x; } - void visit(const AMQHeartbeatBody& x) { frame.body=x; } - void visit(const AMQMethodBody& x) { frame.body=MethodHolder(x); } - }; - friend struct CopyVisitor; - - typedef boost::variant Variant; - - void visit(AMQHeaderBody& x) { body=x; } - - void decodeBody(Buffer& buffer, uint32_t size, uint8_t type); - - bool bof; - bool eof; - bool bos; - bool eos; - uint8_t subchannel; - uint16_t channel; - Variant body; + void init() { bof = eof = bos = eos = true; subchannel=0; channel=0; } + + intrusive_ptr body; + uint16_t channel : 16; + uint8_t subchannel : 8; + bool bof : 1; + bool eof : 1; + bool bos : 1; + bool eos : 1; }; std::ostream& operator<<(std::ostream&, const AMQFrame&); -- cgit v1.2.1