summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Conway <aconway@apache.org>2009-04-20 22:33:27 +0000
committerAlan Conway <aconway@apache.org>2009-04-20 22:33:27 +0000
commita123fa68f68c199faeef3134b2739049fca02ded (patch)
tree64cee55378dfd8577e0f0494e20c38650b722116
parent4e20d749dbde6eabf6bbb78f2eb543af81db949c (diff)
downloadqpid-python-a123fa68f68c199faeef3134b2739049fca02ded.tar.gz
Apply PIMPL pattern to qpid::client::Message.
Hide implementation of Message, move framing::MethodContent and framing::TransferContent out of public API. git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@766899 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--cpp/src/Makefile.am10
-rw-r--r--cpp/src/qpid/client/Dispatcher.cpp3
-rw-r--r--cpp/src/qpid/client/Handle.h6
-rw-r--r--cpp/src/qpid/client/HandlePrivate.h12
-rw-r--r--cpp/src/qpid/client/LocalQueue.cpp3
-rw-r--r--cpp/src/qpid/client/Message.cpp59
-rw-r--r--cpp/src/qpid/client/Message.h55
-rw-r--r--cpp/src/qpid/client/MessageImpl.cpp71
-rw-r--r--cpp/src/qpid/client/MessageImpl.h76
-rw-r--r--cpp/src/qpid/client/PrivateImpl.h54
-rw-r--r--cpp/src/qpid/client/PrivateImplPrivate.h66
-rw-r--r--cpp/src/qpid/client/SessionBase_0_10.h7
-rw-r--r--cpp/src/qpid/client/SubscriptionImpl.cpp7
-rw-r--r--cpp/src/tests/ClientMessageTest.cpp46
-rw-r--r--cpp/src/tests/ClientSessionTest.cpp8
-rw-r--r--cpp/src/tests/Makefile.am3
-rw-r--r--cpp/src/tests/XmlClientSessionTest.cpp2
-rw-r--r--cpp/src/tests/cluster_test.cpp1
18 files changed, 410 insertions, 79 deletions
diff --git a/cpp/src/Makefile.am b/cpp/src/Makefile.am
index ec0e2fc646..4436b507a1 100644
--- a/cpp/src/Makefile.am
+++ b/cpp/src/Makefile.am
@@ -436,21 +436,24 @@ libqpidclient_la_SOURCES = \
qpid/client/Bounds.cpp \
qpid/client/Connection.cpp \
qpid/client/ConnectionHandler.cpp \
- qpid/client/ConnectionImpl.cpp \
+ qpid/client/ConnectionImpl.cpp \
qpid/client/ConnectionSettings.cpp \
- qpid/client/Connector.cpp \
+ qpid/client/Connector.cpp \
qpid/client/Demux.cpp \
qpid/client/Dispatcher.cpp \
- qpid/client/FailoverManager.cpp \
+ qpid/client/FailoverManager.cpp \
qpid/client/FailoverListener.h \
qpid/client/FailoverListener.cpp \
qpid/client/Future.cpp \
qpid/client/FutureCompletion.cpp \
qpid/client/FutureResult.cpp \
qpid/client/HandlePrivate.h \
+ qpid/client/PrivateImplPrivate.h \
qpid/client/LoadPlugins.cpp \
qpid/client/LocalQueue.cpp \
qpid/client/Message.cpp \
+ qpid/client/MessageImpl.cpp \
+ qpid/client/MessageImpl.h \
qpid/client/MessageListener.cpp \
qpid/client/MessageReplayTracker.cpp \
qpid/client/QueueOptions.cpp \
@@ -596,6 +599,7 @@ nobase_include_HEADERS = \
qpid/client/FutureCompletion.h \
qpid/client/FutureResult.h \
qpid/client/Handle.h \
+ qpid/client/PrivateImpl.h \
qpid/client/LocalQueue.h \
qpid/client/QueueOptions.h \
qpid/client/Message.h \
diff --git a/cpp/src/qpid/client/Dispatcher.cpp b/cpp/src/qpid/client/Dispatcher.cpp
index 8ae763b4f3..5156031748 100644
--- a/cpp/src/qpid/client/Dispatcher.cpp
+++ b/cpp/src/qpid/client/Dispatcher.cpp
@@ -26,6 +26,7 @@
#include "qpid/log/Statement.h"
#include "qpid/sys/BlockingQueue.h"
#include "Message.h"
+#include "MessageImpl.h"
#include <boost/state_saver.hpp>
@@ -74,7 +75,7 @@ void Dispatcher::run()
Mutex::ScopedUnlock u(lock);
FrameSet::shared_ptr content = queue->pop();
if (content->isA<MessageTransferBody>()) {
- Message msg(*content);
+ Message msg(new MessageImpl(*content));
boost::intrusive_ptr<SubscriptionImpl> listener = find(msg.getDestination());
if (!listener) {
QPID_LOG(error, "No listener found for destination " << msg.getDestination());
diff --git a/cpp/src/qpid/client/Handle.h b/cpp/src/qpid/client/Handle.h
index 1a092b7209..12fb4cf3c1 100644
--- a/cpp/src/qpid/client/Handle.h
+++ b/cpp/src/qpid/client/Handle.h
@@ -30,9 +30,11 @@ namespace client {
template <class T> class HandlePrivate;
/**
- * A handle is like a pointer: it points to some underlying object.
+ * A handle is like a pointer: it points to some implementation object.
+ * Copying the handle does not copy the object.
+ *
* Handles can be null, like a 0 pointer. Use isValid(), isNull() or the
- * implicit conversion to bool to test for a null handle.
+ * conversion to bool to test for a null handle.
*/
template <class T> class Handle {
public:
diff --git a/cpp/src/qpid/client/HandlePrivate.h b/cpp/src/qpid/client/HandlePrivate.h
index 488ce48075..46e4bff808 100644
--- a/cpp/src/qpid/client/HandlePrivate.h
+++ b/cpp/src/qpid/client/HandlePrivate.h
@@ -21,14 +21,16 @@
* under the License.
*
*/
+#include "Handle.h"
+#include "qpid/RefCounted.h"
#include <algorithm>
+#include <boost/intrusive_ptr.hpp>
namespace qpid {
namespace client {
/** @file
- * Private implementation of handle, include in .cpp file of handle
- * subclasses _after_ including the declaration of class T.
+ * Implementation of handle, include in .cpp file of handle subclasses.
* T can be any class that can be used with boost::intrusive_ptr.
*/
@@ -52,9 +54,13 @@ void Handle<T>::swap(Handle<T>& h) { std::swap(impl, h.impl); }
template <class T>
class HandlePrivate {
public:
- static boost::intrusive_ptr<T> get(Handle<T>& h) { return boost::intrusive_ptr<T>(h.impl); }
+ static boost::intrusive_ptr<T> get(const Handle<T>& h) { return boost::intrusive_ptr<T>(h.impl); }
+ static void set(Handle<T>& h, const boost::intrusive_ptr<T>& p) { Handle<T>(p.get()).swap(h); }
};
+template<class T> boost::intrusive_ptr<T> handleGetPtr(Handle<T>& h) { return HandlePrivate<T>::get(h); }
+template<class T> boost::intrusive_ptr<const T> handleGetPtr(const Handle<T>& h) { return HandlePrivate<T>::get(h); }
+template<class T> void handleSetPtr(Handle<T>& h, const boost::intrusive_ptr<T>& p) { HandlePrivate<T>::set(h, p); }
}} // namespace qpid::client
diff --git a/cpp/src/qpid/client/LocalQueue.cpp b/cpp/src/qpid/client/LocalQueue.cpp
index 481dc0f946..1ff602f3f8 100644
--- a/cpp/src/qpid/client/LocalQueue.cpp
+++ b/cpp/src/qpid/client/LocalQueue.cpp
@@ -19,6 +19,7 @@
*
*/
#include "LocalQueue.h"
+#include "MessageImpl.h"
#include "qpid/Exception.h"
#include "qpid/framing/FrameSet.h"
#include "qpid/framing/MessageTransferBody.h"
@@ -50,7 +51,7 @@ bool LocalQueue::get(Message& result, sys::Duration timeout) {
bool ok = queue->pop(content, timeout);
if (!ok) return false;
if (content->isA<MessageTransferBody>()) {
- result = Message(*content);
+ result = Message(new MessageImpl(*content));
boost::intrusive_ptr<SubscriptionImpl> si = HandlePrivate<SubscriptionImpl>::get(subscription);
assert(si);
if (si) si->received(result);
diff --git a/cpp/src/qpid/client/Message.cpp b/cpp/src/qpid/client/Message.cpp
index 13caaecefd..962ce26305 100644
--- a/cpp/src/qpid/client/Message.cpp
+++ b/cpp/src/qpid/client/Message.cpp
@@ -20,52 +20,37 @@
*/
#include "Message.h"
+#include "PrivateImplPrivate.h"
+#include "MessageImpl.h"
namespace qpid {
namespace client {
-Message::Message(const std::string& data, const std::string& routingKey) : TransferContent(data, routingKey) {}
+template class PrivateImpl<MessageImpl>;
-std::string Message::getDestination() const
-{
- return method.getDestination();
-}
+Message::Message(const std::string& data, const std::string& routingKey) : PrivateImpl<MessageImpl>(new MessageImpl(data, routingKey)) {}
+Message::Message(MessageImpl* i) : PrivateImpl<MessageImpl>(i) {}
+Message::~Message() {}
-bool Message::isRedelivered() const
-{
- return hasDeliveryProperties() && getDeliveryProperties().getRedelivered();
-}
+std::string Message::getDestination() const { return impl->getDestination(); }
+bool Message::isRedelivered() const { return impl->isRedelivered(); }
+void Message::setRedelivered(bool redelivered) { impl->setRedelivered(redelivered); }
+framing::FieldTable& Message::getHeaders() { return impl->getHeaders(); }
+const framing::FieldTable& Message::getHeaders() const { return impl->getHeaders(); }
+const framing::SequenceNumber& Message::getId() const { return impl->getId(); }
-void Message::setRedelivered(bool redelivered)
-{
- getDeliveryProperties().setRedelivered(redelivered);
-}
+void Message::setData(const std::string& s) { impl->setData(s); }
+const std::string& Message::getData() const { return impl->getData(); }
+std::string& Message::getData() { return impl->getData(); }
-framing::FieldTable& Message::getHeaders()
-{
- return getMessageProperties().getApplicationHeaders();
-}
+void Message::appendData(const std::string& s) { impl->appendData(s); }
-const framing::FieldTable& Message::getHeaders() const
-{
- return getMessageProperties().getApplicationHeaders();
-}
+bool Message::hasMessageProperties() const { return impl->hasMessageProperties(); }
+framing::MessageProperties& Message::getMessageProperties() { return impl->getMessageProperties(); }
+const framing::MessageProperties& Message::getMessageProperties() const { return impl->getMessageProperties(); }
-const framing::MessageTransferBody& Message::getMethod() const
-{
- return method;
-}
-
-const framing::SequenceNumber& Message::getId() const
-{
- return id;
-}
-
-/**@internal for incoming messages */
-Message::Message(const framing::FrameSet& frameset) :
- method(*frameset.as<framing::MessageTransferBody>()), id(frameset.getId())
-{
- populate(frameset);
-}
+bool Message::hasDeliveryProperties() const { return impl->hasDeliveryProperties(); }
+framing::DeliveryProperties& Message::getDeliveryProperties() { return impl->getDeliveryProperties(); }
+const framing::DeliveryProperties& Message::getDeliveryProperties() const { return impl->getDeliveryProperties(); }
}}
diff --git a/cpp/src/qpid/client/Message.h b/cpp/src/qpid/client/Message.h
index 235e20f97d..88ba6862eb 100644
--- a/cpp/src/qpid/client/Message.h
+++ b/cpp/src/qpid/client/Message.h
@@ -1,5 +1,5 @@
-#ifndef _client_Message_h
-#define _client_Message_h
+#ifndef QPID_CLIENT_MESSAGE_H
+#define QPID_CLIENT_MESSAGE_H
/*
*
@@ -21,15 +21,24 @@
* under the License.
*
*/
-#include <string>
-#include "qpid/client/Session.h"
-#include "qpid/framing/MessageTransferBody.h"
-#include "qpid/framing/TransferContent.h"
+
+#include "qpid/client/PrivateImpl.h"
#include "qpid/client/ClientImportExport.h"
+#include "qpid/framing/MessageProperties.h"
+#include "qpid/framing/DeliveryProperties.h"
+#include <string>
namespace qpid {
+
+namespace framing {
+class FieldTable;
+class SequenceNumber; // FIXME aconway 2009-04-17: remove with getID?
+}
+
namespace client {
+class MessageImpl;
+
/**
* A message sent to or received from the broker.
*
@@ -104,8 +113,7 @@ namespace client {
*
*
*/
-
-class Message : public framing::TransferContent
+class Message : public PrivateImpl<MessageImpl>
{
public:
/** Create a Message.
@@ -115,6 +123,23 @@ public:
QPID_CLIENT_EXTERN Message(const std::string& data=std::string(),
const std::string& routingKey=std::string());
+ ~Message();
+
+ QPID_CLIENT_EXTERN void setData(const std::string&);
+ QPID_CLIENT_EXTERN const std::string& getData() const;
+ QPID_CLIENT_EXTERN std::string& getData();
+
+ QPID_CLIENT_EXTERN void appendData(const std::string&);
+
+ QPID_CLIENT_EXTERN bool hasMessageProperties() const;
+ QPID_CLIENT_EXTERN framing::MessageProperties& getMessageProperties();
+ QPID_CLIENT_EXTERN const framing::MessageProperties& getMessageProperties() const;
+
+ QPID_CLIENT_EXTERN bool hasDeliveryProperties() const;
+ QPID_CLIENT_EXTERN framing::DeliveryProperties& getDeliveryProperties();
+ QPID_CLIENT_EXTERN const framing::DeliveryProperties& getDeliveryProperties() const;
+
+
/** The destination of messages sent to the broker is the exchange
* name. The destination of messages received from the broker is
* the delivery tag identifyig the local subscription (often this
@@ -133,20 +158,14 @@ public:
/** Get a non-modifyable reference to the message headers. */
QPID_CLIENT_EXTERN const framing::FieldTable& getHeaders() const;
- ///@internal
- QPID_CLIENT_EXTERN const framing::MessageTransferBody& getMethod() const;
+ // FIXME aconway 2009-04-17: does this need to be in public API?
///@internal
QPID_CLIENT_EXTERN const framing::SequenceNumber& getId() const;
- /**@internal for incoming messages */
- QPID_CLIENT_EXTERN Message(const framing::FrameSet& frameset);
-
-private:
- //method and id are only set for received messages:
- framing::MessageTransferBody method;
- framing::SequenceNumber id;
+ ///@internal
+ Message(MessageImpl*);
};
}}
-#endif /*!_client_Message_h*/
+#endif /*!QPID_CLIENT_MESSAGE_H*/
diff --git a/cpp/src/qpid/client/MessageImpl.cpp b/cpp/src/qpid/client/MessageImpl.cpp
new file mode 100644
index 0000000000..3d06fd1d8d
--- /dev/null
+++ b/cpp/src/qpid/client/MessageImpl.cpp
@@ -0,0 +1,71 @@
+/*
+ *
+ * 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 "MessageImpl.h"
+
+namespace qpid {
+namespace client {
+
+MessageImpl::MessageImpl(const std::string& data, const std::string& routingKey) : TransferContent(data, routingKey) {}
+
+std::string MessageImpl::getDestination() const
+{
+ return method.getDestination();
+}
+
+bool MessageImpl::isRedelivered() const
+{
+ return hasDeliveryProperties() && getDeliveryProperties().getRedelivered();
+}
+
+void MessageImpl::setRedelivered(bool redelivered)
+{
+ getDeliveryProperties().setRedelivered(redelivered);
+}
+
+framing::FieldTable& MessageImpl::getHeaders()
+{
+ return getMessageProperties().getApplicationHeaders();
+}
+
+const framing::FieldTable& MessageImpl::getHeaders() const
+{
+ return getMessageProperties().getApplicationHeaders();
+}
+
+const framing::MessageTransferBody& MessageImpl::getMethod() const
+{
+ return method;
+}
+
+const framing::SequenceNumber& MessageImpl::getId() const
+{
+ return id;
+}
+
+/**@internal for incoming messages */
+MessageImpl::MessageImpl(const framing::FrameSet& frameset) :
+ method(*frameset.as<framing::MessageTransferBody>()), id(frameset.getId())
+{
+ populate(frameset);
+}
+
+}}
diff --git a/cpp/src/qpid/client/MessageImpl.h b/cpp/src/qpid/client/MessageImpl.h
new file mode 100644
index 0000000000..c06d9b5afc
--- /dev/null
+++ b/cpp/src/qpid/client/MessageImpl.h
@@ -0,0 +1,76 @@
+#ifndef QPID_CLIENT_MESSAGEIMPL_H
+#define QPID_CLIENT_MESSAGEIMPL_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 <string>
+#include "qpid/client/Session.h"
+#include "qpid/framing/MessageTransferBody.h"
+#include "qpid/framing/TransferContent.h"
+
+namespace qpid {
+namespace client {
+
+class MessageImpl : public framing::TransferContent
+{
+public:
+ /** Create a Message.
+ *@param data Data for the message body.
+ *@param routingKey Passed to the exchange that routes the message.
+ */
+ MessageImpl(const std::string& data=std::string(),
+ const std::string& routingKey=std::string());
+
+ /** The destination of messages sent to the broker is the exchange
+ * name. The destination of messages received from the broker is
+ * the delivery tag identifyig the local subscription (often this
+ * is the name of the subscribed queue.)
+ */
+ std::string getDestination() const;
+
+ /** Check the redelivered flag. */
+ bool isRedelivered() const;
+ /** Set the redelivered flag. */
+ void setRedelivered(bool redelivered);
+
+ /** Get a modifyable reference to the message headers. */
+ framing::FieldTable& getHeaders();
+
+ /** Get a non-modifyable reference to the message headers. */
+ const framing::FieldTable& getHeaders() const;
+
+ ///@internal
+ const framing::MessageTransferBody& getMethod() const;
+ ///@internal
+ const framing::SequenceNumber& getId() const;
+
+ /**@internal for incoming messages */
+ MessageImpl(const framing::FrameSet& frameset);
+
+private:
+ //method and id are only set for received messages:
+ framing::MessageTransferBody method;
+ framing::SequenceNumber id;
+};
+
+}}
+
+#endif /*!QPID_CLIENT_MESSAGEIMPL_H*/
diff --git a/cpp/src/qpid/client/PrivateImpl.h b/cpp/src/qpid/client/PrivateImpl.h
new file mode 100644
index 0000000000..6e5ea35ce0
--- /dev/null
+++ b/cpp/src/qpid/client/PrivateImpl.h
@@ -0,0 +1,54 @@
+#ifndef QPID_CLIENT_PRIVATEIMPL_H
+#define QPID_CLIENT_PRIVATEIMPL_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/client/ClientImportExport.h"
+
+namespace qpid {
+namespace client {
+
+template <class T> class PrivateImplPrivate;
+
+/**
+ * Base classes for objects with a private implementation.
+ *
+ * PrivateImpl objects have value semantics: copying the object also
+ * makes a copy of the implementation.
+ */
+template <class T> class PrivateImpl {
+ public:
+ QPID_CLIENT_EXTERN ~PrivateImpl();
+ QPID_CLIENT_EXTERN PrivateImpl(const PrivateImpl&);
+ QPID_CLIENT_EXTERN PrivateImpl& operator=(const PrivateImpl&);
+ QPID_CLIENT_EXTERN void swap(PrivateImpl<T>&);
+
+ protected:
+ QPID_CLIENT_EXTERN PrivateImpl(T*);
+ T* impl;
+
+ friend class PrivateImplPrivate<T>;
+};
+
+}} // namespace qpid::client
+
+#endif /*!QPID_CLIENT_PRIVATEIMPL_H*/
diff --git a/cpp/src/qpid/client/PrivateImplPrivate.h b/cpp/src/qpid/client/PrivateImplPrivate.h
new file mode 100644
index 0000000000..021456e085
--- /dev/null
+++ b/cpp/src/qpid/client/PrivateImplPrivate.h
@@ -0,0 +1,66 @@
+#ifndef QPID_CLIENT_PRIVATEIMPLPRIVATE_H
+#define QPID_CLIENT_PRIVATEIMPLPRIVATE_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 <algorithm>
+
+namespace qpid {
+namespace client {
+
+/** @file
+ * Implementation of PrivateImpl functions, to include in .cpp file of handle subclasses.
+ * T can be any class with value semantics.
+ */
+
+template <class T>
+PrivateImpl<T>::PrivateImpl(T* p) : impl(p) { assert(impl); }
+
+template <class T>
+PrivateImpl<T>::~PrivateImpl() { delete impl; }
+
+template <class T>
+PrivateImpl<T>::PrivateImpl(const PrivateImpl& h) : impl(new T(*h.impl)) {}
+
+template <class T>
+PrivateImpl<T>& PrivateImpl<T>::operator=(const PrivateImpl<T>& h) { PrivateImpl<T>(h).swap(*this); return *this; }
+
+template <class T>
+void PrivateImpl<T>::swap(PrivateImpl<T>& h) { std::swap(impl, h.impl); }
+
+
+/** Access to private impl of a PrivateImpl */
+template <class T>
+class PrivateImplPrivate {
+ public:
+ static T* get(const PrivateImpl<T>& h) { return h.impl; }
+ static void set(PrivateImpl<T>& h, const T& p) { PrivateImpl<T>(p).swap(h); }
+};
+
+template<class T> T* privateImplGetPtr(PrivateImpl<T>& h) { return PrivateImplPrivate<T>::get(h); }
+template<class T> T* privateImplGetPtr(const PrivateImpl<T>& h) { return PrivateImplPrivate<T>::get(h); }
+template<class T> void privateImplSetPtr(PrivateImpl<T>& h, const T*& p) { PrivateImplPrivate<T>::set(h, p); }
+
+}} // namespace qpid::client
+
+#endif /*!QPID_CLIENT_PRIVATEIMPLPRIVATE_H*/
+
diff --git a/cpp/src/qpid/client/SessionBase_0_10.h b/cpp/src/qpid/client/SessionBase_0_10.h
index afea0cea59..a8c6ada5ae 100644
--- a/cpp/src/qpid/client/SessionBase_0_10.h
+++ b/cpp/src/qpid/client/SessionBase_0_10.h
@@ -24,9 +24,7 @@
#include "qpid/SessionId.h"
#include "qpid/framing/amqp_structs.h"
-#include "qpid/framing/ProtocolVersion.h"
-#include "qpid/framing/MethodContent.h"
-#include "qpid/framing/TransferContent.h"
+#include "qpid/client/Message.h"
#include "qpid/client/Completion.h"
#include "qpid/client/Execution.h"
#include "qpid/client/TypedResult.h"
@@ -42,7 +40,6 @@ class Connection;
using std::string;
using framing::Content;
using framing::FieldTable;
-using framing::MethodContent;
using framing::SequenceNumber;
using framing::SequenceSet;
using framing::SequenceNumberSet;
@@ -61,8 +58,6 @@ enum CreditUnit { MESSAGE_CREDIT=0, BYTE_CREDIT=1, UNLIMITED_CREDIT=0xFFFFFFFF }
class SessionBase_0_10 {
public:
- typedef framing::TransferContent DefaultContent;
-
///@internal
QPID_CLIENT_EXTERN SessionBase_0_10();
QPID_CLIENT_EXTERN ~SessionBase_0_10();
diff --git a/cpp/src/qpid/client/SubscriptionImpl.cpp b/cpp/src/qpid/client/SubscriptionImpl.cpp
index e09a4c142e..1e5fa9f542 100644
--- a/cpp/src/qpid/client/SubscriptionImpl.cpp
+++ b/cpp/src/qpid/client/SubscriptionImpl.cpp
@@ -20,8 +20,11 @@
*/
#include "SubscriptionImpl.h"
+#include "MessageImpl.h"
#include "SubscriptionManager.h"
#include "SubscriptionSettings.h"
+#include "HandlePrivate.h"
+#include "PrivateImplPrivate.h"
namespace qpid {
namespace client {
@@ -114,9 +117,9 @@ void SubscriptionImpl::cancel() { manager.cancel(name); }
void SubscriptionImpl::received(Message& m) {
Mutex::ScopedLock l(lock);
- if (m.getMethod().getAcquireMode() == ACQUIRE_MODE_NOT_ACQUIRED)
+ if (privateImplGetPtr(m)->getMethod().getAcquireMode() == ACQUIRE_MODE_NOT_ACQUIRED)
unacquired.add(m.getId());
- else if (m.getMethod().getAcceptMode() == ACCEPT_MODE_EXPLICIT)
+ else if (privateImplGetPtr(m)->getMethod().getAcceptMode() == ACCEPT_MODE_EXPLICIT)
unaccepted.add(m.getId());
if (listener) {
diff --git a/cpp/src/tests/ClientMessageTest.cpp b/cpp/src/tests/ClientMessageTest.cpp
new file mode 100644
index 0000000000..bc0945674f
--- /dev/null
+++ b/cpp/src/tests/ClientMessageTest.cpp
@@ -0,0 +1,46 @@
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed 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.
+ *
+ */
+
+
+/**@file Unit tests for the client::Message class. */
+
+#include "unit_test.h"
+#include "qpid/client/Message.h"
+
+using namespace qpid::client;
+
+QPID_AUTO_TEST_SUITE(ClientMessageTestSuite)
+
+QPID_AUTO_TEST_CASE(MessageCopyAssign) {
+ // Verify that message has normal copy semantics.
+ Message m("foo");
+ BOOST_CHECK_EQUAL("foo", m.getData());
+ Message c(m);
+ BOOST_CHECK_EQUAL("foo", c.getData());
+ Message a;
+ BOOST_CHECK_EQUAL("", a.getData());
+ a = m;
+ BOOST_CHECK_EQUAL("foo", a.getData());
+ a.setData("a");
+ BOOST_CHECK_EQUAL("a", a.getData());
+ c.setData("c");
+ BOOST_CHECK_EQUAL("c", c.getData());
+ BOOST_CHECK_EQUAL("foo", m.getData());
+}
+
+QPID_AUTO_TEST_SUITE_END()
diff --git a/cpp/src/tests/ClientSessionTest.cpp b/cpp/src/tests/ClientSessionTest.cpp
index 589e1154e1..1c719d16dc 100644
--- a/cpp/src/tests/ClientSessionTest.cpp
+++ b/cpp/src/tests/ClientSessionTest.cpp
@@ -28,7 +28,7 @@
#include "qpid/sys/Runnable.h"
#include "qpid/sys/Time.h"
#include "qpid/client/Session.h"
-#include "qpid/framing/TransferContent.h"
+#include "qpid/client/Message.h"
#include "qpid/framing/reply_exceptions.h"
#include <boost/optional.hpp>
@@ -121,7 +121,7 @@ QPID_AUTO_TEST_CASE(testDispatcher)
fix.session =fix.connection.newSession();
size_t count = 100;
for (size_t i = 0; i < count; ++i)
- fix.session.messageTransfer(arg::content=TransferContent(boost::lexical_cast<string>(i), "my-queue"));
+ fix.session.messageTransfer(arg::content=Message(boost::lexical_cast<string>(i), "my-queue"));
DummyListener listener(fix.session, "my-queue", count);
listener.run();
BOOST_CHECK_EQUAL(count, listener.messages.size());
@@ -137,7 +137,7 @@ QPID_AUTO_TEST_CASE(testDispatcherThread)
DummyListener listener(fix.session, "my-queue", count);
sys::Thread t(listener);
for (size_t i = 0; i < count; ++i) {
- fix.session.messageTransfer(arg::content=TransferContent(boost::lexical_cast<string>(i), "my-queue"));
+ fix.session.messageTransfer(arg::content=Message(boost::lexical_cast<string>(i), "my-queue"));
}
t.join();
BOOST_CHECK_EQUAL(count, listener.messages.size());
@@ -173,7 +173,7 @@ QPID_AUTO_TEST_CASE_EXPECTED_FAILURES(testSuspendResume, 1)
fix.session.suspend();
// Make sure we are still subscribed after resume.
fix.connection.resume(fix.session);
- fix.session.messageTransfer(arg::content=TransferContent("my-message", "my-queue"));
+ fix.session.messageTransfer(arg::content=Message("my-message", "my-queue"));
FrameSet::shared_ptr msg = fix.session.get();
BOOST_CHECK_EQUAL(string("my-message"), msg->getContent());
}
diff --git a/cpp/src/tests/Makefile.am b/cpp/src/tests/Makefile.am
index 9634a629b1..26a13fea48 100644
--- a/cpp/src/tests/Makefile.am
+++ b/cpp/src/tests/Makefile.am
@@ -96,7 +96,8 @@ unit_test_SOURCES= unit_test.cpp unit_test.h \
RetryList.cpp \
RateFlowcontrolTest.cpp \
FrameDecoder.cpp \
- ReplicationTest.cpp
+ ReplicationTest.cpp \
+ ClientMessageTest.cpp
if HAVE_XML
unit_test_SOURCES+= XmlClientSessionTest.cpp
diff --git a/cpp/src/tests/XmlClientSessionTest.cpp b/cpp/src/tests/XmlClientSessionTest.cpp
index 98558f0a76..aeb13c292f 100644
--- a/cpp/src/tests/XmlClientSessionTest.cpp
+++ b/cpp/src/tests/XmlClientSessionTest.cpp
@@ -26,7 +26,7 @@
#include "qpid/sys/Monitor.h"
#include "qpid/sys/Thread.h"
#include "qpid/sys/Runnable.h"
-#include "qpid/framing/TransferContent.h"
+#include "qpid/client/Message.h"
#include "qpid/framing/reply_exceptions.h"
#include "qpid/client/Connection.h"
#include "qpid/client/SubscriptionManager.h"
diff --git a/cpp/src/tests/cluster_test.cpp b/cpp/src/tests/cluster_test.cpp
index 98b399c187..d38d84025b 100644
--- a/cpp/src/tests/cluster_test.cpp
+++ b/cpp/src/tests/cluster_test.cpp
@@ -35,6 +35,7 @@
#include "qpid/framing/Uuid.h"
#include "qpid/framing/reply_exceptions.h"
#include "qpid/framing/enum.h"
+#include "qpid/framing/MessageTransferBody.h"
#include "qpid/log/Logger.h"
#include "qpid/sys/Monitor.h"
#include "qpid/sys/Thread.h"