summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--qpid/cpp/rubygen/framing.0-10/MethodBodyFactory.rb58
-rwxr-xr-xqpid/cpp/rubygen/framing.0-10/MethodHolder.rb118
-rw-r--r--qpid/cpp/rubygen/framing.0-10/structs.rb1
-rw-r--r--qpid/cpp/src/Makefile.am19
-rw-r--r--qpid/cpp/src/qpid/RefCounted.h4
-rw-r--r--qpid/cpp/src/qpid/broker/DeliveryRecord.cpp2
-rw-r--r--qpid/cpp/src/qpid/broker/Message.cpp5
-rw-r--r--qpid/cpp/src/qpid/broker/MessageBuilder.cpp3
-rw-r--r--qpid/cpp/src/qpid/broker/SessionState.cpp3
-rw-r--r--qpid/cpp/src/qpid/client/ConnectionImpl.cpp2
-rw-r--r--qpid/cpp/src/qpid/client/SessionImpl.cpp4
-rw-r--r--qpid/cpp/src/qpid/cluster/Connection.cpp2
-rw-r--r--qpid/cpp/src/qpid/framing/AMQBody.h13
-rw-r--r--qpid/cpp/src/qpid/framing/AMQContentBody.h1
-rw-r--r--qpid/cpp/src/qpid/framing/AMQFrame.cpp45
-rw-r--r--qpid/cpp/src/qpid/framing/AMQFrame.h31
-rw-r--r--qpid/cpp/src/qpid/framing/AMQHeaderBody.h2
-rw-r--r--qpid/cpp/src/qpid/framing/AMQHeartbeatBody.h1
-rw-r--r--qpid/cpp/src/qpid/framing/Array.cpp1
-rw-r--r--qpid/cpp/src/qpid/framing/Blob.h197
-rw-r--r--qpid/cpp/src/qpid/framing/BodyFactory.h47
-rw-r--r--qpid/cpp/src/qpid/framing/BodyHolder.cpp76
-rw-r--r--qpid/cpp/src/qpid/framing/BodyHolder.h88
-rw-r--r--qpid/cpp/src/qpid/framing/FieldTable.cpp1
-rw-r--r--qpid/cpp/src/qpid/framing/MethodBodyFactory.h44
-rw-r--r--qpid/cpp/src/qpid/framing/SendContent.cpp3
-rw-r--r--qpid/cpp/src/qpid/framing/SequenceNumberSet.cpp1
-rw-r--r--qpid/cpp/src/qpid/framing/SequenceSet.cpp1
-rw-r--r--qpid/cpp/src/qpid/management/ManagementBroker.cpp7
-rw-r--r--qpid/cpp/src/qpid/replication/ReplicatingEventListener.cpp6
-rw-r--r--qpid/cpp/src/qpid/sys/Thread.h4
-rw-r--r--qpid/cpp/src/tests/Blob.cpp128
-rw-r--r--qpid/cpp/src/tests/ExchangeTest.cpp4
-rw-r--r--qpid/cpp/src/tests/FramingTest.cpp4
-rw-r--r--qpid/cpp/src/tests/HeaderTest.cpp4
-rw-r--r--qpid/cpp/src/tests/Makefile.am2
-rw-r--r--qpid/cpp/src/tests/MessageBuilderTest.cpp29
-rw-r--r--qpid/cpp/src/tests/MessageTest.cpp9
-rw-r--r--qpid/cpp/src/tests/MessageUtils.h6
-rw-r--r--qpid/cpp/src/tests/QueueTest.cpp4
-rw-r--r--qpid/cpp/src/tests/SessionState.cpp13
-rwxr-xr-xqpid/cpp/src/tests/ssl_test2
42 files changed, 271 insertions, 724 deletions
diff --git a/qpid/cpp/rubygen/framing.0-10/MethodBodyFactory.rb b/qpid/cpp/rubygen/framing.0-10/MethodBodyFactory.rb
new file mode 100644
index 0000000000..95c79fd1a4
--- /dev/null
+++ b/qpid/cpp/rubygen/framing.0-10/MethodBodyFactory.rb
@@ -0,0 +1,58 @@
+#!/usr/bin/env ruby
+#
+# 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 .. in load path
+require 'cppgen'
+
+class MethodBodyFactoryGen < CppGen
+
+ def initialize(outdir, amqp)
+ super(outdir, amqp)
+ @namespace="qpid::framing"
+ @classname="MethodBodyFactory"
+ @filename="qpid/framing/MethodBodyFactory"
+ end
+
+ def generate()
+ cpp_file(@filename) {
+ include @filename
+ include "qpid/framing/BodyFactory"
+ @amqp.methods_.each { |m| include "qpid/framing/#{m.body_name}" }
+ include "qpid/Exception.h"
+ genl
+ namespace(@namespace) {
+ scope("boost::intrusive_ptr<AMQMethodBody> #{@classname}::create(ClassId c, MethodId m) {") {
+ scope("switch (c) {") {
+ @amqp.classes.each { |c|
+ scope("case #{c.code}: switch(m) {") {
+ c.methods_.each { |m|
+ genl "case #{m.code}: return BodyFactory::create<#{m.body_name}>();"
+ }
+ genl "default: throw Exception(QPID_MSG(\"Invalid method id \" << int(m) << \" for class #{c.name} \"));"
+ }
+ genl "break;"
+ }
+ genl "default: throw Exception(QPID_MSG(\"Invalid class id \" << int(c)));"
+ }
+ }
+ }}
+ end
+end
+
+MethodBodyFactoryGen.new($outdir, $amqp).generate();
diff --git a/qpid/cpp/rubygen/framing.0-10/MethodHolder.rb b/qpid/cpp/rubygen/framing.0-10/MethodHolder.rb
index a2801d0907..e69de29bb2 100755
--- a/qpid/cpp/rubygen/framing.0-10/MethodHolder.rb
+++ b/qpid/cpp/rubygen/framing.0-10/MethodHolder.rb
@@ -1,118 +0,0 @@
-#!/usr/bin/env ruby
-#
-# 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 .. in load path
-require 'cppgen'
-
-class MethodHolderGen < CppGen
-
- def initialize(outdir, amqp)
- super(outdir, amqp)
- @namespace="qpid::framing"
- @classname="BodyHolder"
- @filename="qpid/framing/BodyHolder"
- end
-
- def gen_max_size()
- # Generate program to generate MaxSize.h
- cpp_file("generate_MaxMethodBodySize_h") {
- include "qpid/framing/AMQHeaderBody"
- include "qpid/framing/AMQContentBody"
- include "qpid/framing/AMQHeartbeatBody"
- @amqp.methods_.each { |m| include "qpid/framing/#{m.body_name}" }
- genl
- include "<algorithm>"
- include "<fstream>"
- genl
- genl "using namespace std;"
- genl "using namespace qpid::framing;"
- genl
- scope("int main(int, char** argv) {") {
- genl "size_t maxSize=0;"
- genl "maxSize=max(maxSize, sizeof(AMQHeaderBody));"
- genl "maxSize=max(maxSize, sizeof(AMQContentBody));"
- genl "maxSize=max(maxSize, sizeof(AMQHeartbeatBody));"
- @amqp.methods_.each { |m|
- genl "maxSize=max(maxSize, sizeof(#{m.body_name}));" }
- gen <<EOS
-ofstream out("qpid/framing/MaxMethodBodySize.h");
-out << "// GENERATED CODE: generated by " << argv[0] << endl;
-out << "namespace qpid{ namespace framing { " << endl;
-out << "const size_t MAX_METHOD_BODY_SIZE=" << maxSize << ";" << endl;
-out << "}}" << endl;
-EOS
- }
- }
- end
-
- def gen_construct
- cpp_file(@filename+"_gen") {
- include @filename
- include "qpid/framing/AMQHeaderBody"
- include "qpid/framing/AMQContentBody"
- include "qpid/framing/AMQHeartbeatBody"
- @amqp.methods_.each { |m| include "qpid/framing/#{m.body_name}" }
- include "qpid/framing/FrameDefaultVisitor.h"
- include "qpid/Exception.h"
- genl
- namespace(@namespace) {
- scope("void #{@classname}::setMethod(ClassId c, MethodId m) {") {
- scope("switch (c) {") {
- @amqp.classes.each { |c|
- scope("case #{c.code}: switch(m) {") {
- c.methods_.each { |m|
- genl "case #{m.code}: blob = in_place<#{m.body_name}>(); break;"
- }
- genl "default: throw Exception(QPID_MSG(\"Invalid method id \" << int(m) << \" for class #{c.name} \"));"
- }
- genl "break;"
- }
- genl "default: throw Exception(QPID_MSG(\"Invalid class id \" << int(c)));"
- }
- }
-
- struct("CopyVisitor", "public FrameDefaultVisitor") {
- genl "using FrameDefaultVisitor::visit;"
- genl "using FrameDefaultVisitor::defaultVisit;"
- genl "BodyHolder& holder;"
- genl "CopyVisitor(BodyHolder& h) : holder(h) {}"
- ["Header", "Content", "Heartbeat"].each { |type|
- genl "void visit(const AMQ#{type}Body& x) { holder=x; }"
- }
- @amqp.methods_.each { |m|
- genl "void visit(const #{m.body_name}& x) { holder=x; }"
- }
- genl "void defaultVisit(const AMQBody&) { assert(0); }"
- }
- genl
-
- scope("void BodyHolder::setBody(const AMQBody& b) {") {
- genl "CopyVisitor cv(*this); b.accept(cv);"
- }
- }}
- end
-
- def generate
- gen_max_size
- gen_construct
- end
-end
-
-MethodHolderGen.new($outdir, $amqp).generate();
-
diff --git a/qpid/cpp/rubygen/framing.0-10/structs.rb b/qpid/cpp/rubygen/framing.0-10/structs.rb
index eb935d06b4..a68e1afb1e 100644
--- a/qpid/cpp/rubygen/framing.0-10/structs.rb
+++ b/qpid/cpp/rubygen/framing.0-10/structs.rb
@@ -233,6 +233,7 @@ class StructGen < CppGen
using AMQMethodBody::accept;
void accept(MethodBodyConstVisitor& v) const { v.visit(*this); }
+ boost::intrusive_ptr<AMQBody> clone() const { return BodyFactory::copy(*this); }
ClassId amqpClassId() const { return CLASS_ID; }
MethodId amqpMethodId() const { return METHOD_ID; }
diff --git a/qpid/cpp/src/Makefile.am b/qpid/cpp/src/Makefile.am
index f97abf24f2..56c7cf39e1 100644
--- a/qpid/cpp/src/Makefile.am
+++ b/qpid/cpp/src/Makefile.am
@@ -27,7 +27,6 @@ windows_dist = \
broker.vcproj \
common.vcproj \
client.vcproj \
- MaxMethodBodySize.vcproj \
qmfconsole.vcproj \
protocol_gen.mak \
qpid/log/windows/SinkOptions.cpp \
@@ -99,14 +98,6 @@ endif # GENERATE
include $(srcdir)/rubygen.mk
include $(srcdir)/managementgen.mk
-# Code generated by C++
-noinst_PROGRAMS=generate_MaxMethodBodySize_h
-generate_MaxMethodBodySize_h_SOURCES=gen/generate_MaxMethodBodySize_h.cpp
-qpid/framing/MaxMethodBodySize.h: generate_MaxMethodBodySize_h
- ./generate_MaxMethodBodySize_h
-BUILT_SOURCES=qpid/framing/MaxMethodBodySize.h
-DISTCLEANFILES=qpid/framing/MaxMethodBodySize.h
-
## Compiler flags
AM_CXXFLAGS = $(WARNING_CFLAGS)
AM_LDFLAGS = -version-info $(LIBTOOL_VERSION_INFO_ARG)
@@ -231,7 +222,7 @@ cmodule_LTLIBRARIES += \
rdmaconnector.la
# RDMA test/sample programs
-noinst_PROGRAMS += RdmaServer RdmaClient
+noinst_PROGRAMS = RdmaServer RdmaClient
RdmaServer_SOURCES = qpid/sys/rdma/RdmaServer.cpp
RdmaServer_LDADD = \
librdmawrap.la libqpidcommon.la
@@ -318,7 +309,6 @@ libqpidcommon_la_SOURCES = \
qpid/framing/AMQHeaderBody.cpp \
qpid/framing/AMQHeartbeatBody.cpp \
qpid/framing/Array.cpp \
- qpid/framing/BodyHolder.cpp \
qpid/framing/BodyHandler.cpp \
qpid/framing/Buffer.cpp \
qpid/framing/Endian.cpp \
@@ -335,8 +325,6 @@ libqpidcommon_la_SOURCES = \
qpid/framing/Proxy.cpp \
qpid/framing/Uuid.cpp \
qpid/framing/AMQP_HighestVersion.h \
- qpid/framing/Blob.cpp \
- qpid/framing/MaxMethodBodySize.h \
qpid/framing/TransferContent.cpp \
qpid/log/Logger.cpp \
qpid/log/Options.cpp \
@@ -624,9 +612,9 @@ nobase_include_HEADERS = \
qpid/framing/AMQP_HighestVersion.h \
qpid/framing/AccumulatedAck.h \
qpid/framing/Array.h \
- qpid/framing/Blob.h \
qpid/framing/BodyHandler.h \
- qpid/framing/BodyHolder.h \
+ qpid/framing/BodyFactory.h \
+ qpid/framing/MethodBodyFactory.h \
qpid/framing/Buffer.h \
qpid/framing/ChannelHandler.h \
qpid/framing/Endian.h \
@@ -642,7 +630,6 @@ nobase_include_HEADERS = \
qpid/framing/InputHandler.h \
qpid/framing/InitiationHandler.h \
qpid/framing/MethodContent.h \
- qpid/framing/MaxMethodBodySize.h \
qpid/framing/ModelMethod.h \
qpid/framing/OutputHandler.h \
qpid/framing/ProtocolInitiation.h \
diff --git a/qpid/cpp/src/qpid/RefCounted.h b/qpid/cpp/src/qpid/RefCounted.h
index 10b5e4afcc..e7a9bf31c1 100644
--- a/qpid/cpp/src/qpid/RefCounted.h
+++ b/qpid/cpp/src/qpid/RefCounted.h
@@ -39,11 +39,13 @@ class RefCounted : boost::noncopyable {
public:
RefCounted() : count(0) {}
void addRef() const { ++count; }
- void release() const { if (--count==0) delete this; }
+ void release() const { if (--count==0) released(); }
long refCount() { return count; }
protected:
virtual ~RefCounted() {};
+ // Allow subclasses to over-ride behavior when refcount reaches 0.
+ virtual void released() const { delete this; }
};
diff --git a/qpid/cpp/src/qpid/broker/DeliveryRecord.cpp b/qpid/cpp/src/qpid/broker/DeliveryRecord.cpp
index 90ec67f477..432a44ec63 100644
--- a/qpid/cpp/src/qpid/broker/DeliveryRecord.cpp
+++ b/qpid/cpp/src/qpid/broker/DeliveryRecord.cpp
@@ -93,7 +93,7 @@ void DeliveryRecord::deliver(framing::FrameHandler& h, DeliveryId deliveryId, ui
msg.payload->getProperties<framing::DeliveryProperties>()->setRedelivered(true);
}
- framing::AMQFrame method(framing::in_place<framing::MessageTransferBody>(framing::ProtocolVersion(), tag, acceptExpected ? 0 : 1, acquired ? 0 : 1));
+ framing::AMQFrame method((framing::MessageTransferBody(framing::ProtocolVersion(), tag, acceptExpected ? 0 : 1, acquired ? 0 : 1)));
method.setEof(false);
h.handle(method);
msg.payload->sendHeader(h, framesize);
diff --git a/qpid/cpp/src/qpid/broker/Message.cpp b/qpid/cpp/src/qpid/broker/Message.cpp
index 89f2653a21..6bcee99f49 100644
--- a/qpid/cpp/src/qpid/broker/Message.cpp
+++ b/qpid/cpp/src/qpid/broker/Message.cpp
@@ -157,8 +157,7 @@ void Message::decodeContent(framing::Buffer& buffer)
if (buffer.available()) {
//get the data as a string and set that as the content
//body on a frame then add that frame to the frameset
- AMQFrame frame;
- frame.setBody(AMQContentBody());
+ AMQFrame frame((AMQContentBody()));
frame.castBody<AMQContentBody>()->decode(buffer, buffer.available());
frames.append(frame);
} else {
@@ -208,7 +207,7 @@ void Message::sendContent(Queue& queue, framing::FrameHandler& out, uint16_t max
bool done = false;
for (uint64_t offset = 0; !done; offset += maxContentSize)
{
- AMQFrame frame(in_place<AMQContentBody>());
+ AMQFrame frame((AMQContentBody()));
string& data = frame.castBody<AMQContentBody>()->getData();
store->loadContent(queue, pmsg, data, offset, maxContentSize);
diff --git a/qpid/cpp/src/qpid/broker/MessageBuilder.cpp b/qpid/cpp/src/qpid/broker/MessageBuilder.cpp
index 8f0e3344d5..1e988021b2 100644
--- a/qpid/cpp/src/qpid/broker/MessageBuilder.cpp
+++ b/qpid/cpp/src/qpid/broker/MessageBuilder.cpp
@@ -49,8 +49,7 @@ void MessageBuilder::handle(AMQFrame& frame)
if (type == CONTENT_BODY) {
//TODO: rethink how to handle non-existent headers(?)...
//didn't get a header: add in a dummy
- AMQFrame header;
- header.setBody(AMQHeaderBody());
+ AMQFrame header((AMQHeaderBody()));
header.setBof(false);
header.setEof(false);
message->getFrames().append(header);
diff --git a/qpid/cpp/src/qpid/broker/SessionState.cpp b/qpid/cpp/src/qpid/broker/SessionState.cpp
index d0804d66b9..e17a813db7 100644
--- a/qpid/cpp/src/qpid/broker/SessionState.cpp
+++ b/qpid/cpp/src/qpid/broker/SessionState.cpp
@@ -188,8 +188,7 @@ void SessionState::handleContent(AMQFrame& frame, const SequenceNumber& id)
if (frame.getEof() && frame.getEos()) {//end of frameset
if (frame.getBof()) {
//i.e this is a just a command frame, add a dummy header
- AMQFrame header;
- header.setBody(AMQHeaderBody());
+ AMQFrame header((AMQHeaderBody()));
header.setBof(false);
header.setEof(false);
msg->getFrames().append(header);
diff --git a/qpid/cpp/src/qpid/client/ConnectionImpl.cpp b/qpid/cpp/src/qpid/client/ConnectionImpl.cpp
index d0e47b774f..8e27d78479 100644
--- a/qpid/cpp/src/qpid/client/ConnectionImpl.cpp
+++ b/qpid/cpp/src/qpid/client/ConnectionImpl.cpp
@@ -164,7 +164,7 @@ void ConnectionImpl::idleIn()
void ConnectionImpl::idleOut()
{
- AMQFrame frame(in_place<AMQHeartbeatBody>());
+ AMQFrame frame((AMQHeartbeatBody()));
connector->send(frame);
}
diff --git a/qpid/cpp/src/qpid/client/SessionImpl.cpp b/qpid/cpp/src/qpid/client/SessionImpl.cpp
index ab8c1bddb8..4fadf236f8 100644
--- a/qpid/cpp/src/qpid/client/SessionImpl.cpp
+++ b/qpid/cpp/src/qpid/client/SessionImpl.cpp
@@ -364,7 +364,7 @@ void SessionImpl::sendContent(const MethodContent& content)
const uint32_t frag_size = maxFrameSize - AMQFrame::frameOverhead();
if(data_length < frag_size){
- AMQFrame frame(in_place<AMQContentBody>(content.getData()));
+ AMQFrame frame((AMQContentBody(content.getData())));
frame.setFirstSegment(false);
handleOut(frame);
}else{
@@ -373,7 +373,7 @@ void SessionImpl::sendContent(const MethodContent& content)
while (remaining > 0) {
uint32_t length = remaining > frag_size ? frag_size : remaining;
string frag(content.getData().substr(offset, length));
- AMQFrame frame(in_place<AMQContentBody>(frag));
+ AMQFrame frame((AMQContentBody(frag)));
frame.setFirstSegment(false);
frame.setLastSegment(true);
if (offset > 0) {
diff --git a/qpid/cpp/src/qpid/cluster/Connection.cpp b/qpid/cpp/src/qpid/cluster/Connection.cpp
index a255acfc1f..3988abd491 100644
--- a/qpid/cpp/src/qpid/cluster/Connection.cpp
+++ b/qpid/cpp/src/qpid/cluster/Connection.cpp
@@ -109,7 +109,7 @@ void Connection::received(framing::AMQFrame& f) {
QPID_LOG(debug, cluster << " inserting connection " << *this);
cluster.insert(boost::intrusive_ptr<Connection>(this));
}
- AMQFrame ok(in_place<ConnectionCloseOkBody>());
+ AMQFrame ok((ConnectionCloseOkBody()));
connection.getOutput().send(ok);
output.setOutputHandler(discardHandler);
catchUp = false;
diff --git a/qpid/cpp/src/qpid/framing/AMQBody.h b/qpid/cpp/src/qpid/framing/AMQBody.h
index 93f4319575..9e66b9738f 100644
--- a/qpid/cpp/src/qpid/framing/AMQBody.h
+++ b/qpid/cpp/src/qpid/framing/AMQBody.h
@@ -22,7 +22,9 @@
*
*/
#include "qpid/framing/amqp_types.h"
-
+#include "qpid/RefCounted.h"
+#include "qpid/framing/BodyFactory.h"
+#include <boost/intrusive_ptr.hpp>
#include <ostream>
namespace qpid {
@@ -43,11 +45,15 @@ struct AMQBodyConstVisitor {
virtual void visit(const AMQMethodBody&) = 0;
};
-class AMQBody
-{
+class AMQBody : public RefCounted {
public:
+ AMQBody() {}
virtual ~AMQBody();
+ // Make AMQBody copyable even though RefCounted.
+ AMQBody(const AMQBody&) : RefCounted() {}
+ AMQBody& operator=(const AMQBody&) { return *this; }
+
virtual uint8_t type() const = 0;
virtual void encode(Buffer& buffer) const = 0;
@@ -62,6 +68,7 @@ class AMQBody
/** Match if same type and same class/method ID for methods */
static bool match(const AMQBody& , const AMQBody& );
+ virtual boost::intrusive_ptr<AMQBody> clone() const = 0;
};
std::ostream& operator<<(std::ostream& out, const AMQBody& body) ;
diff --git a/qpid/cpp/src/qpid/framing/AMQContentBody.h b/qpid/cpp/src/qpid/framing/AMQContentBody.h
index 288f1549a9..a81cf36168 100644
--- a/qpid/cpp/src/qpid/framing/AMQContentBody.h
+++ b/qpid/cpp/src/qpid/framing/AMQContentBody.h
@@ -44,6 +44,7 @@ public:
void decode(Buffer& buffer, uint32_t size);
void print(std::ostream& out) const;
void accept(AMQBodyConstVisitor& v) const { v.visit(*this); }
+ boost::intrusive_ptr<AMQBody> clone() const { return BodyFactory::copy(*this); }
};
}
diff --git a/qpid/cpp/src/qpid/framing/AMQFrame.cpp b/qpid/cpp/src/qpid/framing/AMQFrame.cpp
index 98a1354811..7ef0db08cb 100644
--- a/qpid/cpp/src/qpid/framing/AMQFrame.cpp
+++ b/qpid/cpp/src/qpid/framing/AMQFrame.cpp
@@ -20,25 +20,31 @@
*/
#include "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 {
-AMQFrame::~AMQFrame() {}
+void AMQFrame::init() { bof = eof = bos = eos = true; subchannel=0; channel=0; }
+
+AMQFrame::AMQFrame(const boost::intrusive_ptr<AMQBody>& b) : body(b) { init(); }
+
+AMQFrame::AMQFrame(const AMQBody& b) : body(b.clone()) { init(); }
-void AMQFrame::setBody(const AMQBody& b) { body = new BodyHolder(b); }
+AMQFrame::~AMQFrame() {}
-void AMQFrame::setMethod(ClassId c, MethodId m) { body = new BodyHolder(c,m); }
+void AMQFrame::setMethod(ClassId c, MethodId m) { body = MethodBodyFactory::create(c,m); }
uint32_t AMQFrame::encodedSize() const {
- return frameOverhead() + body->encodedSize();
+ uint32_t size = frameOverhead() + body->encodedSize();
+ if (body->getMethod())
+ size += sizeof(ClassId)+sizeof(MethodId);
+ return size;
}
uint32_t AMQFrame::frameOverhead() {
@@ -65,6 +71,11 @@ void AMQFrame::encode(Buffer& buffer) const
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);
}
@@ -105,8 +116,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);
+
return true;
}
diff --git a/qpid/cpp/src/qpid/framing/AMQFrame.h b/qpid/cpp/src/qpid/framing/AMQFrame.h
index 7bf4638089..f1ea2f8b82 100644
--- a/qpid/cpp/src/qpid/framing/AMQFrame.h
+++ b/qpid/cpp/src/qpid/framing/AMQFrame.h
@@ -26,47 +26,29 @@
#include "AMQContentBody.h"
#include "AMQHeartbeatBody.h"
#include "ProtocolVersion.h"
-#include "BodyHolder.h"
#include "qpid/sys/LatencyMetric.h"
-
#include <boost/intrusive_ptr.hpp>
#include <boost/cast.hpp>
namespace qpid {
namespace framing {
-class BodyHolder;
-
class AMQFrame : public AMQDataBlock, public sys::LatencyMetricTimestamp
{
public:
- AMQFrame(boost::intrusive_ptr<BodyHolder> b=0) : body(b) { init(); }
- AMQFrame(const AMQBody& b) { setBody(b); init(); }
+ AMQFrame(const boost::intrusive_ptr<AMQBody>& b=0);
+ AMQFrame(const AMQBody& b);
~AMQFrame();
- template <class InPlace>
- AMQFrame(const InPlace& ip, typename EnableInPlace<InPlace>::type* =0) {
- init(); setBody(ip);
- }
-
ChannelId getChannel() const { return channel; }
void setChannel(ChannelId c) { channel = c; }
- boost::intrusive_ptr<BodyHolder> getHolder() { return body; }
-
- AMQBody* getBody() { return body ? body->get() : 0; }
- const AMQBody* getBody() const { return body ? body->get() : 0; }
+ AMQBody* getBody() { return body.get(); }
+ const AMQBody* getBody() const { return body.get(); }
AMQMethodBody* getMethod() { return getBody()->getMethod(); }
const AMQMethodBody* getMethod() const { return getBody()->getMethod(); }
- void setBody(const AMQBody& b);
-
- template <class InPlace>
- typename EnableInPlace<InPlace>::type setBody(const InPlace& ip) {
- body = new BodyHolder(ip);
- }
-
void setMethod(ClassId c, MethodId m);
template <class T> T* castBody() {
@@ -109,10 +91,11 @@ class AMQFrame : public AMQDataBlock, public sys::LatencyMetricTimestamp
static uint32_t frameOverhead();
/** Must point to at least DECODE_SIZE_MIN bytes of data */
static uint16_t decodeSize(char* data);
+
private:
- void init() { bof = eof = bos = eos = true; subchannel=0; channel=0; }
+ void init();
- boost::intrusive_ptr<BodyHolder> body;
+ boost::intrusive_ptr<AMQBody> body;
uint16_t channel : 16;
uint8_t subchannel : 8;
bool bof : 1;
diff --git a/qpid/cpp/src/qpid/framing/AMQHeaderBody.h b/qpid/cpp/src/qpid/framing/AMQHeaderBody.h
index 7ddb7d89cf..9846544949 100644
--- a/qpid/cpp/src/qpid/framing/AMQHeaderBody.h
+++ b/qpid/cpp/src/qpid/framing/AMQHeaderBody.h
@@ -99,6 +99,8 @@ public:
template <class T> const T* get() const {
return properties.OptProps<T>::props.get_ptr();
}
+
+ boost::intrusive_ptr<AMQBody> clone() const { return BodyFactory::copy(*this); }
};
}}
diff --git a/qpid/cpp/src/qpid/framing/AMQHeartbeatBody.h b/qpid/cpp/src/qpid/framing/AMQHeartbeatBody.h
index 7b42b46e5c..3fb41c128e 100644
--- a/qpid/cpp/src/qpid/framing/AMQHeartbeatBody.h
+++ b/qpid/cpp/src/qpid/framing/AMQHeartbeatBody.h
@@ -38,6 +38,7 @@ public:
inline void decode(Buffer& , uint32_t /*size*/) {}
virtual void print(std::ostream& out) const;
void accept(AMQBodyConstVisitor& v) const { v.visit(*this); }
+ boost::intrusive_ptr<AMQBody> clone() const { return BodyFactory::copy(*this); }
};
}
diff --git a/qpid/cpp/src/qpid/framing/Array.cpp b/qpid/cpp/src/qpid/framing/Array.cpp
index 9f072f7b05..a4eb5a29ab 100644
--- a/qpid/cpp/src/qpid/framing/Array.cpp
+++ b/qpid/cpp/src/qpid/framing/Array.cpp
@@ -75,6 +75,7 @@ void Array::encode(Buffer& buffer) const{
}
void Array::decode(Buffer& buffer){
+ values.clear();
uint32_t size = buffer.getLong();//size added only when array is a top-level type
uint32_t available = buffer.available();
if (available < size) {
diff --git a/qpid/cpp/src/qpid/framing/Blob.h b/qpid/cpp/src/qpid/framing/Blob.h
index 5c84384ad7..e69de29bb2 100644
--- a/qpid/cpp/src/qpid/framing/Blob.h
+++ b/qpid/cpp/src/qpid/framing/Blob.h
@@ -1,197 +0,0 @@
-#ifndef QPID_FRAMING_BLOB_H
-#define QPID_FRAMING_BLOB_H
-
-/*
- * 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 <boost/static_assert.hpp>
-#include <boost/aligned_storage.hpp>
-#include <boost/checked_delete.hpp>
-#include <boost/utility/typed_in_place_factory.hpp>
-#include <boost/type_traits/is_base_and_derived.hpp>
-#include <boost/utility/enable_if.hpp>
-#include <boost/version.hpp>
-
-#include <new>
-
-#include <assert.h>
-
-
-namespace qpid {
-namespace framing {
-
-using boost::in_place;
-using boost::typed_in_place_factory_base;
-
-/** 0-arg typed_in_place_factory, missing in pre-1.35 boost. */
-#if (BOOST_VERSION < 103500)
-template <class T>
-struct typed_in_place_factory0 : public typed_in_place_factory_base {
- typedef T value_type ;
- void apply ( void* address ) const { new (address) T(); }
-};
-
-/** 0-arg in_place<T>() function, missing from boost. */
-template<class T>
-typed_in_place_factory0<T> in_place() { return typed_in_place_factory0<T>(); }
-#endif
-
-template <class T, class R=void>
-struct EnableInPlace
- : public boost::enable_if<boost::is_base_and_derived<
- typed_in_place_factory_base, T>,
- R>
-{};
-
-template <class T, class R=void>
-struct DisableInPlace
- : public boost::disable_if<boost::is_base_and_derived<
- typed_in_place_factory_base, T>,
- R>
-{};
-
-template <class T> struct BlobHelper {
- static void destroy(void* ptr) { static_cast<T*>(ptr)->~T(); }
- static void copy(void* dest, const void* src) {
- new (dest) T(*static_cast<const T*>(src));
- }
-};
-
-template <> struct BlobHelper<void> {
- static void destroy(void*);
- static void copy(void* to, const void* from);
-};
-
-/**
- * A Blob is a chunk of memory which can contain a single object at
- * a time-arbitrary type, provided sizeof(T)<=blob.size(). Using Blobs
- * ensures proper construction and destruction of its contents,
- * and proper copying between Blobs, but nothing else.
- *
- * In particular you must ensure that the Blob is big enough for its
- * contents and must know the type of object in the Blob to cast get().
- *
- * If BaseType is specified then only an object that can be
- * static_cast to BaseType may be stored in the Blob.
- */
-template <size_t Size, class BaseType=void>
-class Blob
-{
- boost::aligned_storage<Size> store;
- BaseType* basePtr;
-
- void (*destroy)(void*);
- void (*copy)(void*, const void*);
-
- template <class T>void setType() {
- BOOST_STATIC_ASSERT(sizeof(T) <= Size);
- destroy=&BlobHelper<T>::destroy;
- copy=&BlobHelper<T>::copy;
- // Base pointer may be offeset from store.address()
- basePtr = reinterpret_cast<T*>(store.address());
- }
-
- void initialize() {
- destroy=&BlobHelper<void>::destroy;
- copy=&BlobHelper<void>::copy;
- basePtr=0;
- }
-
- template<class Factory>
- typename EnableInPlace<Factory>::type apply(const Factory& factory)
- {
- typedef typename Factory::value_type T;
- assert(empty());
- factory.apply(store.address());
- setType<T>();
- }
-
- void assign(const Blob& b) {
- assert(empty());
- if (b.empty()) return;
- b.copy(this->store.address(), b.store.address());
- copy = b.copy;
- destroy = b.destroy;
- basePtr = reinterpret_cast<BaseType*>(
- ((char*)this)+ ((const char*)(b.basePtr) - (const char*)(&b)));
- }
-
- public:
- /** Construct an empty Blob. */
- Blob() { initialize(); }
-
- /** Copy a Blob. */
- Blob(const Blob& b) { initialize(); assign(b); }
-
- /** Construct from in_place constructor. */
- template<class InPlace>
- Blob(const InPlace & expr, typename EnableInPlace<InPlace>::type* =0) {
- initialize(); apply(expr);
- }
-
- /** Construct by copying an object constructor. */
- template<class T>
- Blob(const T & t, typename DisableInPlace<T>::type* =0) {
- initialize(); apply(in_place<T>(t));
- }
-
- ~Blob() { clear(); }
-
- /** Assign from another Blob. */
- Blob& operator=(const Blob& b) {
- clear();
- assign(b);
- return *this;
- }
-
- /** Assign from an in_place constructor expression. */
- template<class InPlace>
- typename EnableInPlace<InPlace,Blob&>::type operator=(const InPlace& expr) {
- clear(); apply(expr); return *this;
- }
-
- /** Assign from an object of type T. */
- template <class T>
- typename DisableInPlace<T, Blob&>::type operator=(const T& x) {
- clear(); apply(in_place<T>(x)); return *this;
- }
-
- /** Get pointer to Blob contents, returns 0 if empty. */
- BaseType* get() { return basePtr; }
-
- /** Get pointer to Blob contents, returns 0 if empty. */
- const BaseType* get() const { return basePtr; }
-
- /** Destroy the object in the Blob making it empty. */
- void clear() {
- void (*oldDestroy)(void*) = destroy;
- initialize();
- oldDestroy(store.address());
- }
-
- bool empty() const { return destroy==BlobHelper<void>::destroy; }
-
- static size_t size() { return Size; }
-};
-
-}} // namespace qpid::framing
-
-
-#endif /*!QPID_FRAMING_BLOB_H*/
diff --git a/qpid/cpp/src/qpid/framing/BodyFactory.h b/qpid/cpp/src/qpid/framing/BodyFactory.h
new file mode 100644
index 0000000000..6a8d9b1988
--- /dev/null
+++ b/qpid/cpp/src/qpid/framing/BodyFactory.h
@@ -0,0 +1,47 @@
+#ifndef QPID_FRAMING_BODYFACTORY_H
+#define QPID_FRAMING_BODYFACTORY_H
+
+/*
+ *
+ * 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 <boost/intrusive_ptr.hpp>
+
+namespace qpid {
+namespace framing {
+
+/**
+ * Indirect creation of body types to allow centralized changes to
+ * memory management strategy.
+ */
+class BodyFactory {
+ public:
+ template <class BodyType> static boost::intrusive_ptr<BodyType> create() {
+ return new BodyType;
+ }
+
+ template <class BodyType> static boost::intrusive_ptr<BodyType> copy(const BodyType& body) {
+ return new BodyType(body);
+ }
+};
+
+}} // namespace qpid::framing
+
+#endif /*!QPID_FRAMING_BODYFACTORY_H*/
diff --git a/qpid/cpp/src/qpid/framing/BodyHolder.cpp b/qpid/cpp/src/qpid/framing/BodyHolder.cpp
index b30a52a38e..e69de29bb2 100644
--- a/qpid/cpp/src/qpid/framing/BodyHolder.cpp
+++ b/qpid/cpp/src/qpid/framing/BodyHolder.cpp
@@ -1,76 +0,0 @@
-/*
- *
- * 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 "BodyHolder.h"
-#include "AMQMethodBody.h"
-#include "AMQHeaderBody.h"
-#include "AMQContentBody.h"
-#include "AMQHeartbeatBody.h"
-#include "Buffer.h"
-#include "qpid/framing/reply_exceptions.h"
-
-namespace qpid {
-namespace framing {
-
-
-// BodyHolder::operator=(const AMQBody&) is defined
-// in generated file BodyHolder_gen.cpp
-
-
-void BodyHolder::encode(Buffer& b) const {
- const AMQMethodBody* method=getMethod();
- if (method) {
- b.putOctet(method->amqpClassId());
- b.putOctet(method->amqpMethodId());
- method->encode(b);
- }
- else
- get()->encode(b);
-}
-
-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();
- setMethod(c, m);
- break;
- }
- case HEADER_BODY: *this=in_place<AMQHeaderBody>(); break;
- case CONTENT_BODY: *this=in_place<AMQContentBody>(); break;
- case HEARTBEAT_BODY: *this=in_place<AMQHeartbeatBody>(); break;
- default:
- throw IllegalArgumentException(QPID_MSG("Invalid frame type " << type));
- }
- get()->decode(buffer, size);
-}
-
-uint32_t BodyHolder::encodedSize() const {
- const AMQMethodBody* method=getMethod();
- if (method)
- return sizeof(ClassId)+sizeof(MethodId)+method->encodedSize();
- else
- return get()->encodedSize();
-}
-
-}} // namespace qpid::framing
-
diff --git a/qpid/cpp/src/qpid/framing/BodyHolder.h b/qpid/cpp/src/qpid/framing/BodyHolder.h
index 0a35bb5e99..e69de29bb2 100644
--- a/qpid/cpp/src/qpid/framing/BodyHolder.h
+++ b/qpid/cpp/src/qpid/framing/BodyHolder.h
@@ -1,88 +0,0 @@
-#ifndef QPID_FRAMING_BODYHOLDER_H
-#define QPID_FRAMING_BODYHOLDER_H
-
-/*
- *
- * 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 "qpid/framing/AMQBody.h"
-#include "qpid/framing/Blob.h"
-#include "qpid/framing/MaxMethodBodySize.h" // Generated file.
-#include "qpid/framing/amqp_types.h"
-#include "qpid/RefCounted.h"
-
-
-namespace qpid {
-namespace framing {
-
-class AMQMethodBody;
-class AMQBody;
-class Buffer;
-
-/**
- * Holder for arbitrary frame body.
- */
-class BodyHolder : public RefCounted
-{
- public:
- // default copy, assign dtor ok.
- BodyHolder() {}
- BodyHolder(const AMQBody& b) { setBody(b); }
- BodyHolder(ClassId c, MethodId m) { setMethod(c,m); }
-
- /** Construct from an in_place constructor expression. */
- template <class InPlace>
- BodyHolder(const InPlace& ip, typename EnableInPlace<InPlace>::type* =0)
- : blob(ip) {}
-
- void setBody(const AMQBody& b);
-
- /** Assign from an in_place constructor expression. */
- template <class InPlace>
- typename EnableInPlace<InPlace,BodyHolder&>::type
- operator=(const InPlace& ip) { blob=ip; return *this; }
-
- /** Assign by copying. */
- template <class T>
- typename DisableInPlace<T,BodyHolder&>::type operator=(const T& x)
- { blob=in_place<T>(x); return *this; }
-
- /** Set to method with ClassId c, MethodId m. */
- void setMethod(ClassId c, MethodId m);
-
- void encode(Buffer&) const;
- void decode(uint8_t frameType, Buffer&, uint32_t=0);
- uint32_t encodedSize() const;
-
- /** Return body pointer or 0 if empty. */
- AMQBody* get() { return blob.get(); }
- const AMQBody* get() const { return blob.get(); }
-
- /** Return method pointer or 0 if not a method. */
- AMQMethodBody* getMethod() { return get()->getMethod(); }
- const AMQMethodBody* getMethod() const { return get()->getMethod(); }
-
- private:
- Blob<MAX_METHOD_BODY_SIZE, AMQBody> blob;
-};
-
-}} // namespace qpid::framing
-
-#endif /*!QPID_FRAMING_BODYHOLDER_H*/
diff --git a/qpid/cpp/src/qpid/framing/FieldTable.cpp b/qpid/cpp/src/qpid/framing/FieldTable.cpp
index 7260261970..559aa8b013 100644
--- a/qpid/cpp/src/qpid/framing/FieldTable.cpp
+++ b/qpid/cpp/src/qpid/framing/FieldTable.cpp
@@ -201,6 +201,7 @@ void FieldTable::encode(Buffer& buffer) const{
}
void FieldTable::decode(Buffer& buffer){
+ clear();
uint32_t len = buffer.getLong();
if (len) {
uint32_t available = buffer.available();
diff --git a/qpid/cpp/src/qpid/framing/MethodBodyFactory.h b/qpid/cpp/src/qpid/framing/MethodBodyFactory.h
new file mode 100644
index 0000000000..da20407b6e
--- /dev/null
+++ b/qpid/cpp/src/qpid/framing/MethodBodyFactory.h
@@ -0,0 +1,44 @@
+#ifndef QPID_FRAMING_METHODBODYFACTORY_H
+#define QPID_FRAMING_METHODBODYFACTORY_H
+
+/*
+ *
+ * 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 "amqp_types.h"
+#include <boost/intrusive_ptr.hpp>
+
+namespace qpid {
+namespace framing {
+
+class AMQMethodBody;
+
+/**
+ * Functions to create instances of AMQMethodBody sub-classes.
+ * Note: MethodBodyFactory.cpp file is generated by rubygen.
+ */
+class MethodBodyFactory
+{
+ public:
+ static boost::intrusive_ptr<AMQMethodBody> create(ClassId c, MethodId m);
+};
+
+}} // namespace qpid::framing
+
+#endif /*!QPID_FRAMING_METHODBODYFACTORY_H*/
diff --git a/qpid/cpp/src/qpid/framing/SendContent.cpp b/qpid/cpp/src/qpid/framing/SendContent.cpp
index f390106dee..2b8287a5c2 100644
--- a/qpid/cpp/src/qpid/framing/SendContent.cpp
+++ b/qpid/cpp/src/qpid/framing/SendContent.cpp
@@ -53,8 +53,7 @@ void qpid::framing::SendContent::operator()(const AMQFrame& f)
void qpid::framing::SendContent::sendFragment(const AMQContentBody& body, uint32_t offset, uint16_t size, bool first, bool last) const
{
- AMQFrame fragment(in_place<AMQContentBody>(
- body.getData().substr(offset, size)));
+ AMQFrame fragment((AMQContentBody(body.getData().substr(offset, size))));
setFlags(fragment, first, last);
handler.handle(fragment);
}
diff --git a/qpid/cpp/src/qpid/framing/SequenceNumberSet.cpp b/qpid/cpp/src/qpid/framing/SequenceNumberSet.cpp
index afab9033e5..58db2614fb 100644
--- a/qpid/cpp/src/qpid/framing/SequenceNumberSet.cpp
+++ b/qpid/cpp/src/qpid/framing/SequenceNumberSet.cpp
@@ -33,6 +33,7 @@ void SequenceNumberSet::encode(Buffer& buffer) const
void SequenceNumberSet::decode(Buffer& buffer)
{
+ clear();
uint16_t count = (buffer.getShort() / 4);
for (uint16_t i = 0; i < count; i++) {
push_back(SequenceNumber(buffer.getLong()));
diff --git a/qpid/cpp/src/qpid/framing/SequenceSet.cpp b/qpid/cpp/src/qpid/framing/SequenceSet.cpp
index 2046fac3e1..1c913e68f8 100644
--- a/qpid/cpp/src/qpid/framing/SequenceSet.cpp
+++ b/qpid/cpp/src/qpid/framing/SequenceSet.cpp
@@ -46,6 +46,7 @@ void SequenceSet::encode(Buffer& buffer) const
void SequenceSet::decode(Buffer& buffer)
{
+ clear();
uint16_t size = buffer.getShort();
uint16_t count = size / RANGE_SIZE;//number of ranges
if (size % RANGE_SIZE)
diff --git a/qpid/cpp/src/qpid/management/ManagementBroker.cpp b/qpid/cpp/src/qpid/management/ManagementBroker.cpp
index cc7a2dc4f3..2175bc4676 100644
--- a/qpid/cpp/src/qpid/management/ManagementBroker.cpp
+++ b/qpid/cpp/src/qpid/management/ManagementBroker.cpp
@@ -301,10 +301,9 @@ void ManagementBroker::sendBuffer(Buffer& buf,
return;
intrusive_ptr<Message> msg(new Message());
- AMQFrame method(in_place<MessageTransferBody>(
- ProtocolVersion(), exchange->getName (), 0, 0));
- AMQFrame header(in_place<AMQHeaderBody>());
- AMQFrame content(in_place<AMQContentBody>());
+ AMQFrame method((MessageTransferBody(ProtocolVersion(), exchange->getName (), 0, 0)));
+ AMQFrame header((AMQHeaderBody()));
+ AMQFrame content((AMQContentBody()));
content.castBody<AMQContentBody>()->decode(buf, length);
diff --git a/qpid/cpp/src/qpid/replication/ReplicatingEventListener.cpp b/qpid/cpp/src/qpid/replication/ReplicatingEventListener.cpp
index d50ef852ef..52634e5640 100644
--- a/qpid/cpp/src/qpid/replication/ReplicatingEventListener.cpp
+++ b/qpid/cpp/src/qpid/replication/ReplicatingEventListener.cpp
@@ -77,8 +77,8 @@ void ReplicatingEventListener::deliverEnqueueMessage(const QueuedMessage& enqueu
boost::intrusive_ptr<Message> ReplicatingEventListener::createMessage(const FieldTable& headers)
{
boost::intrusive_ptr<Message> msg(new Message());
- AMQFrame method(in_place<MessageTransferBody>(ProtocolVersion(), EMPTY, 0, 0));
- AMQFrame header(in_place<AMQHeaderBody>());
+ AMQFrame method((MessageTransferBody(ProtocolVersion(), EMPTY, 0, 0)));
+ AMQFrame header((AMQHeaderBody()));
header.setBof(false);
header.setEof(true);
header.setBos(true);
@@ -105,7 +105,7 @@ struct AppendingHandler : FrameHandler
boost::intrusive_ptr<Message> ReplicatingEventListener::cloneMessage(Queue& queue, boost::intrusive_ptr<Message> original)
{
boost::intrusive_ptr<Message> copy(new Message());
- AMQFrame method(in_place<MessageTransferBody>(ProtocolVersion(), EMPTY, 0, 0));
+ AMQFrame method((MessageTransferBody(ProtocolVersion(), EMPTY, 0, 0)));
AppendingHandler handler(copy);
handler.handle(method);
original->sendHeader(handler, std::numeric_limits<int16_t>::max());
diff --git a/qpid/cpp/src/qpid/sys/Thread.h b/qpid/cpp/src/qpid/sys/Thread.h
index 2fd59621d8..e2b904aa1a 100644
--- a/qpid/cpp/src/qpid/sys/Thread.h
+++ b/qpid/cpp/src/qpid/sys/Thread.h
@@ -25,10 +25,10 @@
#ifdef _WIN32
# define QPID_TSS __declspec(thread)
-#elif defined (gcc)
+#elif defined (__GNUC__)
# define QPID_TSS __thread
#else
-# define QPID_TSS
+# error "Dont know how to define QPID_TSS for this platform"
#endif
namespace qpid {
diff --git a/qpid/cpp/src/tests/Blob.cpp b/qpid/cpp/src/tests/Blob.cpp
index c40e43b96e..e69de29bb2 100644
--- a/qpid/cpp/src/tests/Blob.cpp
+++ b/qpid/cpp/src/tests/Blob.cpp
@@ -1,128 +0,0 @@
-/*
- * 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 "qpid/framing/Blob.h"
-
-#include "unit_test.h"
-
-QPID_AUTO_TEST_SUITE(BlobTestSuite)
-
-using namespace std;
-using namespace qpid::framing;
-
-struct Base {
- int id;
- int magic;
-
- Base(int n) : id(n), magic(42) {}
- Base(const Base& c) : id(c.id), magic(42) {}
- ~Base() { BOOST_CHECK_EQUAL(42, magic); } // Detect random data.
-};
-
-template <class T> struct Count : public Base {
- static int instances;
- bool destroyed;
-
- Count(int n) : Base(n), destroyed(false) { ++instances; }
- Count(const Count& c) : Base(c), destroyed(false) { ++instances; }
- ~Count() {
- BOOST_CHECK(!destroyed); // Detect double-destructor
- destroyed=true;
- BOOST_CHECK(--instances >= 0);
- }
-};
-
-template <class T> int Count<T>::instances = 0;
-
-struct Foo : public Count<Foo> { Foo(int n) : Count<Foo>(n) {}; };
-struct Bar : public Count<Bar> { Bar(int n) : Count<Bar>(n) {}; };
-
-typedef Blob<sizeof(Foo), Base> TestBlob ;
-
-QPID_AUTO_TEST_CASE(testBlobCtor) {
- {
- TestBlob empty;
- BOOST_CHECK(empty.empty());
- BOOST_CHECK(empty.get() == 0);
-
- TestBlob empty2(empty);
- BOOST_CHECK(empty2.empty());
-
- TestBlob foo(in_place<Foo>(1));
- BOOST_CHECK(!foo.empty());
- BOOST_CHECK_EQUAL(1, foo.get()->id);
- BOOST_CHECK_EQUAL(1, Foo::instances);
-
- TestBlob foo2(foo);
- BOOST_CHECK(!foo2.empty());
- BOOST_CHECK_EQUAL(1, foo2.get()->id);
- BOOST_CHECK_EQUAL(2, Foo::instances);
- }
-
- BOOST_CHECK_EQUAL(0, Foo::instances);
- BOOST_CHECK_EQUAL(0, Bar::instances);
-}
-
-
-QPID_AUTO_TEST_CASE(testAssign) {
- {
- TestBlob b;
- b = Foo(2);
- BOOST_CHECK_EQUAL(2, b.get()->id);
- BOOST_CHECK_EQUAL(1, Foo::instances);
-
- TestBlob b2(b);
- BOOST_CHECK_EQUAL(2, b.get()->id);
- BOOST_CHECK_EQUAL(2, Foo::instances);
-
- b2 = Bar(3);
- BOOST_CHECK_EQUAL(3, b2.get()->id);
- BOOST_CHECK_EQUAL(1, Foo::instances);
- BOOST_CHECK_EQUAL(1, Bar::instances);
-
- b2 = in_place<Foo>(4);
- BOOST_CHECK_EQUAL(4, b2.get()->id);
- BOOST_CHECK_EQUAL(2, Foo::instances);
- BOOST_CHECK_EQUAL(0, Bar::instances);
-
- b2.clear();
- BOOST_CHECK(b2.empty());
- BOOST_CHECK_EQUAL(1, Foo::instances);
- }
- BOOST_CHECK_EQUAL(0, Foo::instances);
- BOOST_CHECK_EQUAL(0, Bar::instances);
-}
-
-
-QPID_AUTO_TEST_CASE(testClear) {
- TestBlob b(in_place<Foo>(5));
- TestBlob c(b);
- BOOST_CHECK(!c.empty());
- BOOST_CHECK(!b.empty());
- BOOST_CHECK_EQUAL(2, Foo::instances);
-
- c.clear();
- BOOST_CHECK(c.empty());
- BOOST_CHECK_EQUAL(1, Foo::instances);
-
- b.clear();
- BOOST_CHECK(b.empty());
- BOOST_CHECK_EQUAL(0, Foo::instances);
-}
-
-QPID_AUTO_TEST_SUITE_END()
diff --git a/qpid/cpp/src/tests/ExchangeTest.cpp b/qpid/cpp/src/tests/ExchangeTest.cpp
index 0946d3115d..2100fb5ed7 100644
--- a/qpid/cpp/src/tests/ExchangeTest.cpp
+++ b/qpid/cpp/src/tests/ExchangeTest.cpp
@@ -167,8 +167,8 @@ QPID_AUTO_TEST_CASE(testDeleteGetAndRedeclare)
intrusive_ptr<Message> cmessage(std::string exchange, std::string routingKey) {
intrusive_ptr<Message> msg(new Message());
- AMQFrame method(in_place<MessageTransferBody>(ProtocolVersion(), exchange, 0, 0));
- AMQFrame header(in_place<AMQHeaderBody>());
+ AMQFrame method((MessageTransferBody(ProtocolVersion(), exchange, 0, 0)));
+ AMQFrame header((AMQHeaderBody()));
msg->getFrames().append(method);
msg->getFrames().append(header);
msg->getFrames().getHeaders()->get<DeliveryProperties>(true)->setRoutingKey(routingKey);
diff --git a/qpid/cpp/src/tests/FramingTest.cpp b/qpid/cpp/src/tests/FramingTest.cpp
index f82507c0a7..e09ee19bc2 100644
--- a/qpid/cpp/src/tests/FramingTest.cpp
+++ b/qpid/cpp/src/tests/FramingTest.cpp
@@ -123,7 +123,7 @@ QPID_AUTO_TEST_CASE(testConnectionRedirectBodyFrame)
hosts.add(boost::shared_ptr<FieldValue>(new Str16Value(a)));
hosts.add(boost::shared_ptr<FieldValue>(new Str16Value(b)));
- AMQFrame in(in_place<ConnectionRedirectBody>(version, a, hosts));
+ AMQFrame in((ConnectionRedirectBody(version, a, hosts)));
in.setChannel(999);
in.encode(wbuff);
@@ -138,7 +138,7 @@ QPID_AUTO_TEST_CASE(testMessageCancelBodyFrame)
char buffer[1024];
ProtocolVersion version(highestProtocolVersion);
Buffer wbuff(buffer, sizeof(buffer));
- AMQFrame in(in_place<MessageCancelBody>(version, "tag"));
+ AMQFrame in((MessageCancelBody(version, "tag")));
in.setChannel(999);
in.encode(wbuff);
diff --git a/qpid/cpp/src/tests/HeaderTest.cpp b/qpid/cpp/src/tests/HeaderTest.cpp
index 33bf705e65..01e7c22ee6 100644
--- a/qpid/cpp/src/tests/HeaderTest.cpp
+++ b/qpid/cpp/src/tests/HeaderTest.cpp
@@ -49,7 +49,7 @@ QPID_AUTO_TEST_CASE(testGenericProperties)
QPID_AUTO_TEST_CASE(testMessageProperties)
{
- AMQFrame out(in_place<AMQHeaderBody>());
+ AMQFrame out((AMQHeaderBody()));
MessageProperties* props1 =
out.castBody<AMQHeaderBody>()->get<MessageProperties>(true);
@@ -84,7 +84,7 @@ QPID_AUTO_TEST_CASE(testMessageProperties)
QPID_AUTO_TEST_CASE(testDeliveryProperies)
{
- AMQFrame out(in_place<AMQHeaderBody>());
+ AMQFrame out((AMQHeaderBody()));
DeliveryProperties* props1 =
out.castBody<AMQHeaderBody>()->get<DeliveryProperties>(true);
diff --git a/qpid/cpp/src/tests/Makefile.am b/qpid/cpp/src/tests/Makefile.am
index 6392322f9a..d675b587b1 100644
--- a/qpid/cpp/src/tests/Makefile.am
+++ b/qpid/cpp/src/tests/Makefile.am
@@ -54,7 +54,7 @@ unit_test_SOURCES= unit_test.cpp unit_test.h \
BrokerFixture.h SocketProxy.h \
exception_test.cpp \
RefCounted.cpp \
- SessionState.cpp Blob.cpp logging.cpp \
+ SessionState.cpp logging.cpp \
AsyncCompletion.cpp \
Url.cpp Uuid.cpp \
Shlib.cpp FieldValue.cpp FieldTable.cpp Array.cpp \
diff --git a/qpid/cpp/src/tests/MessageBuilderTest.cpp b/qpid/cpp/src/tests/MessageBuilderTest.cpp
index 313a91c053..a183742832 100644
--- a/qpid/cpp/src/tests/MessageBuilderTest.cpp
+++ b/qpid/cpp/src/tests/MessageBuilderTest.cpp
@@ -101,9 +101,8 @@ QPID_AUTO_TEST_CASE(testHeaderOnly)
std::string exchange("builder-exchange");
std::string key("builder-exchange");
- AMQFrame method(in_place<MessageTransferBody>(
- ProtocolVersion(), exchange, 0, 0));
- AMQFrame header(in_place<AMQHeaderBody>());
+ AMQFrame method((MessageTransferBody(ProtocolVersion(), exchange, 0, 0)));
+ AMQFrame header((AMQHeaderBody()));
header.castBody<AMQHeaderBody>()->get<MessageProperties>(true)->setContentLength(0);
header.castBody<AMQHeaderBody>()->get<DeliveryProperties>(true)->setRoutingKey(key);
@@ -126,9 +125,9 @@ QPID_AUTO_TEST_CASE(test1ContentFrame)
std::string exchange("builder-exchange");
std::string key("builder-exchange");
- AMQFrame method(in_place<MessageTransferBody>(ProtocolVersion(), exchange, 0, 0));
- AMQFrame header(in_place<AMQHeaderBody>());
- AMQFrame content(in_place<AMQContentBody>(data));
+ AMQFrame method((MessageTransferBody(ProtocolVersion(), exchange, 0, 0)));
+ AMQFrame header((AMQHeaderBody()));
+ AMQFrame content((AMQContentBody(data)));
method.setEof(false);
header.setBof(false);
header.setEof(false);
@@ -160,11 +159,10 @@ QPID_AUTO_TEST_CASE(test2ContentFrames)
std::string exchange("builder-exchange");
std::string key("builder-exchange");
- AMQFrame method(in_place<MessageTransferBody>(
- ProtocolVersion(), exchange, 0, 0));
- AMQFrame header(in_place<AMQHeaderBody>());
- AMQFrame content1(in_place<AMQContentBody>(data1));
- AMQFrame content2(in_place<AMQContentBody>(data2));
+ AMQFrame method((MessageTransferBody(ProtocolVersion(), exchange, 0, 0)));
+ AMQFrame header((AMQHeaderBody()));
+ AMQFrame content1((AMQContentBody(data1)));
+ AMQFrame content2((AMQContentBody(data2)));
method.setEof(false);
header.setBof(false);
header.setEof(false);
@@ -197,11 +195,10 @@ QPID_AUTO_TEST_CASE(testStaging)
std::string exchange("builder-exchange");
std::string key("builder-exchange");
- AMQFrame method(in_place<MessageTransferBody>(
- ProtocolVersion(), exchange, 0, 0));
- AMQFrame header(in_place<AMQHeaderBody>());
- AMQFrame content1(in_place<AMQContentBody>(data1));
- AMQFrame content2(in_place<AMQContentBody>(data2));
+ AMQFrame method(MessageTransferBody(ProtocolVersion(), exchange, 0, 0));
+ AMQFrame header((AMQHeaderBody()));
+ AMQFrame content1((AMQContentBody(data1)));
+ AMQFrame content2((AMQContentBody(data2)));
header.castBody<AMQHeaderBody>()->get<MessageProperties>(true)->setContentLength(data1.size() + data2.size());
header.castBody<AMQHeaderBody>()->get<DeliveryProperties>(true)->setRoutingKey(key);
diff --git a/qpid/cpp/src/tests/MessageTest.cpp b/qpid/cpp/src/tests/MessageTest.cpp
index f9292ee53e..8fd9a53c7c 100644
--- a/qpid/cpp/src/tests/MessageTest.cpp
+++ b/qpid/cpp/src/tests/MessageTest.cpp
@@ -46,11 +46,10 @@ QPID_AUTO_TEST_CASE(testEncodeDecode)
intrusive_ptr<Message> msg(new Message());
- AMQFrame method(in_place<MessageTransferBody>(
- ProtocolVersion(), exchange, 0, 0));
- AMQFrame header(in_place<AMQHeaderBody>());
- AMQFrame content1(in_place<AMQContentBody>(data1));
- AMQFrame content2(in_place<AMQContentBody>(data2));
+ AMQFrame method((MessageTransferBody(ProtocolVersion(), exchange, 0, 0)));
+ AMQFrame header((AMQHeaderBody()));
+ AMQFrame content1((AMQContentBody(data1)));
+ AMQFrame content2((AMQContentBody(data2)));
msg->getFrames().append(method);
msg->getFrames().append(header);
diff --git a/qpid/cpp/src/tests/MessageUtils.h b/qpid/cpp/src/tests/MessageUtils.h
index 81508e534e..67a852aa10 100644
--- a/qpid/cpp/src/tests/MessageUtils.h
+++ b/qpid/cpp/src/tests/MessageUtils.h
@@ -35,8 +35,8 @@ struct MessageUtils
{
boost::intrusive_ptr<Message> msg(new Message());
- AMQFrame method(in_place<MessageTransferBody>(ProtocolVersion(), exchange, 0, 0));
- AMQFrame header(in_place<AMQHeaderBody>());
+ AMQFrame method(( MessageTransferBody(ProtocolVersion(), exchange, 0, 0)));
+ AMQFrame header((AMQHeaderBody()));
msg->getFrames().append(method);
msg->getFrames().append(header);
@@ -49,7 +49,7 @@ struct MessageUtils
static void addContent(boost::intrusive_ptr<Message> msg, const string& data)
{
- AMQFrame content(in_place<AMQContentBody>(data));
+ AMQFrame content((AMQContentBody(data)));
msg->getFrames().append(content);
}
};
diff --git a/qpid/cpp/src/tests/QueueTest.cpp b/qpid/cpp/src/tests/QueueTest.cpp
index dee6de83a7..079b9b0ba6 100644
--- a/qpid/cpp/src/tests/QueueTest.cpp
+++ b/qpid/cpp/src/tests/QueueTest.cpp
@@ -67,8 +67,8 @@ public:
intrusive_ptr<Message> create_message(std::string exchange, std::string routingKey) {
intrusive_ptr<Message> msg(new Message());
- AMQFrame method(in_place<MessageTransferBody>(ProtocolVersion(), exchange, 0, 0));
- AMQFrame header(in_place<AMQHeaderBody>());
+ AMQFrame method((MessageTransferBody(ProtocolVersion(), exchange, 0, 0)));
+ AMQFrame header((AMQHeaderBody()));
msg->getFrames().append(method);
msg->getFrames().append(header);
msg->getFrames().getHeaders()->get<DeliveryProperties>(true)->setRoutingKey(routingKey);
diff --git a/qpid/cpp/src/tests/SessionState.cpp b/qpid/cpp/src/tests/SessionState.cpp
index 2db25f9fe8..5e21ff2b70 100644
--- a/qpid/cpp/src/tests/SessionState.cpp
+++ b/qpid/cpp/src/tests/SessionState.cpp
@@ -45,8 +45,7 @@ T applyAccumulate(Iter begin, Iter end, T seed, const F& f) {
// Create a frame with a one-char string.
AMQFrame& frame(char s) {
- static AMQFrame frame;
- frame.setBody(AMQContentBody(string(&s, 1)));
+ static AMQFrame frame((AMQContentBody(string(&s, 1))));
return frame;
}
@@ -64,7 +63,7 @@ string str(const boost::iterator_range<vector<AMQFrame>::const_iterator>& frames
}
// Make a transfer command frame.
AMQFrame transferFrame(bool hasContent) {
- AMQFrame t(in_place<MessageTransferBody>());
+ AMQFrame t((MessageTransferBody()));
t.setFirstFrame(true);
t.setLastFrame(true);
t.setFirstSegment(true);
@@ -73,7 +72,7 @@ AMQFrame transferFrame(bool hasContent) {
}
// Make a content frame
AMQFrame contentFrame(string content, bool isLast=true) {
- AMQFrame f(in_place<AMQContentBody>(content));
+ AMQFrame f((AMQContentBody(content)));
f.setFirstFrame(true);
f.setLastFrame(true);
f.setFirstSegment(false);
@@ -116,8 +115,8 @@ size_t transfers(qpid::SessionState& s, string content) {
bind(transfer1Char, ref(s), _1));
}
-size_t contentFrameSize(size_t n=1) { return AMQFrame(in_place<AMQContentBody>()).encodedSize() + n; }
-size_t transferFrameSize() { return AMQFrame(in_place<MessageTransferBody>()).encodedSize(); }
+size_t contentFrameSize(size_t n=1) { return AMQFrame(( AMQContentBody())).encodedSize() + n; }
+size_t transferFrameSize() { return AMQFrame((MessageTransferBody())).encodedSize(); }
// ==== qpid::SessionState test classes
@@ -134,7 +133,7 @@ QPID_AUTO_TEST_CASE(testSendGetReplyList) {
transferN(s, "xyz");
BOOST_CHECK_EQUAL(str(s.senderExpected(SessionPoint(0,0))),"CabcCdCeCfCxyz");
// Ignore controls.
- s.senderRecord(AMQFrame(in_place<SessionFlushBody>()));
+ s.senderRecord(AMQFrame(new SessionFlushBody()));
BOOST_CHECK_EQUAL(str(s.senderExpected(SessionPoint(2,0))),"CeCfCxyz");
}
diff --git a/qpid/cpp/src/tests/ssl_test b/qpid/cpp/src/tests/ssl_test
index 047db93d20..c7b59b62ef 100755
--- a/qpid/cpp/src/tests/ssl_test
+++ b/qpid/cpp/src/tests/ssl_test
@@ -25,7 +25,7 @@ CONFIG=$(dirname $0)/config.null
CERT_DIR=`pwd`/test_cert_db
CERT_PW_FILE=`pwd`/cert.password
HOSTNAME=`hostname`
-COUNT=10000
+COUNT=10
trap stop_broker EXIT