summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src')
-rw-r--r--cpp/src/Makefile.am9
-rw-r--r--cpp/src/qpid/client/amqp0_10/AddressResolution.cpp11
-rw-r--r--cpp/src/qpid/client/amqp0_10/IncomingMessages.cpp11
-rw-r--r--cpp/src/qpid/client/amqp0_10/OutgoingMessage.cpp17
-rw-r--r--cpp/src/qpid/messaging/ListContent.cpp98
-rw-r--r--cpp/src/qpid/messaging/ListView.cpp63
-rw-r--r--cpp/src/qpid/messaging/MapContent.cpp87
-rw-r--r--cpp/src/qpid/messaging/MapView.cpp63
-rw-r--r--cpp/src/qpid/messaging/Message.cpp28
-rw-r--r--cpp/src/qpid/messaging/MessageImpl.cpp149
-rw-r--r--cpp/src/qpid/messaging/MessageImpl.h54
-rw-r--r--cpp/src/tests/MessagingSessionTests.cpp83
12 files changed, 385 insertions, 288 deletions
diff --git a/cpp/src/Makefile.am b/cpp/src/Makefile.am
index 4988f3f031..9ff8fb42a2 100644
--- a/cpp/src/Makefile.am
+++ b/cpp/src/Makefile.am
@@ -686,6 +686,10 @@ libqpidclient_la_SOURCES = \
qpid/messaging/Address.cpp \
qpid/messaging/Connection.cpp \
qpid/messaging/Filter.cpp \
+ qpid/messaging/ListContent.cpp \
+ qpid/messaging/ListView.cpp \
+ qpid/messaging/MapContent.cpp \
+ qpid/messaging/MapView.cpp \
qpid/messaging/Message.cpp \
qpid/messaging/MessageImpl.h \
qpid/messaging/MessageImpl.cpp \
@@ -790,8 +794,11 @@ nobase_include_HEADERS += \
../include/qpid/messaging/Connection.h \
../include/qpid/messaging/Codec.h \
../include/qpid/messaging/Filter.h \
+ ../include/qpid/messaging/ListContent.h \
+ ../include/qpid/messaging/ListView.h \
+ ../include/qpid/messaging/MapContent.h \
+ ../include/qpid/messaging/MapView.h \
../include/qpid/messaging/Message.h \
- ../include/qpid/messaging/MessageContent.h \
../include/qpid/messaging/MessageListener.h \
../include/qpid/messaging/Sender.h \
../include/qpid/messaging/Receiver.h \
diff --git a/cpp/src/qpid/client/amqp0_10/AddressResolution.cpp b/cpp/src/qpid/client/amqp0_10/AddressResolution.cpp
index 9b9f06ec57..f51a96efd9 100644
--- a/cpp/src/qpid/client/amqp0_10/AddressResolution.cpp
+++ b/cpp/src/qpid/client/amqp0_10/AddressResolution.cpp
@@ -362,21 +362,12 @@ void QueueSink::send(qpid::client::AsyncSession& session, const std::string&, Ou
void QueueSink::cancel(qpid::client::AsyncSession&, const std::string&) {}
-template <class T> void encode(qpid::messaging::Message& from)
-{
- T codec;
- from.encode(codec);
- from.setContentType(T::contentType);
-}
-
void translate(const Variant::Map& from, FieldTable& to);//implementation in Codecs.cpp
void convert(qpid::messaging::Message& from, qpid::client::Message& to)
{
//TODO: need to avoid copying as much as possible
- if (from.getContent().isList()) encode<ListCodec>(from);
- if (from.getContent().isMap()) encode<MapCodec>(from);
- to.setData(from.getBytes());
+ to.setData(from.getContent());
to.getDeliveryProperties().setRoutingKey(from.getSubject());
//TODO: set other delivery properties
to.getMessageProperties().setContentType(from.getContentType());
diff --git a/cpp/src/qpid/client/amqp0_10/IncomingMessages.cpp b/cpp/src/qpid/client/amqp0_10/IncomingMessages.cpp
index d22208368b..8e060c62d7 100644
--- a/cpp/src/qpid/client/amqp0_10/IncomingMessages.cpp
+++ b/cpp/src/qpid/client/amqp0_10/IncomingMessages.cpp
@@ -269,18 +269,9 @@ void populate(qpid::messaging::Message& message, FrameSet& command)
//e.g. for rejecting.
MessageImplAccess::get(message).setInternalId(command.getId());
- command.getContent(message.getBytes());
+ command.getContent(message.getContent());
populateHeaders(message, command.getHeaders());
-
- //decode content if necessary
- if (message.getContentType() == ListCodec::contentType) {
- ListCodec codec;
- message.decode(codec);
- } else if (message.getContentType() == MapCodec::contentType) {
- MapCodec codec;
- message.decode(codec);
- }
}
diff --git a/cpp/src/qpid/client/amqp0_10/OutgoingMessage.cpp b/cpp/src/qpid/client/amqp0_10/OutgoingMessage.cpp
index 716f955f98..cbc95b44fb 100644
--- a/cpp/src/qpid/client/amqp0_10/OutgoingMessage.cpp
+++ b/cpp/src/qpid/client/amqp0_10/OutgoingMessage.cpp
@@ -33,24 +33,11 @@ namespace amqp0_10 {
using qpid::messaging::Address;
using qpid::messaging::MessageImplAccess;
-template <class T> void encode(const qpid::messaging::Message& from, qpid::client::Message& to)
-{
- T codec;
- MessageImplAccess::get(from).getEncodedContent(codec, to.getData());
- to.getMessageProperties().setContentType(T::contentType);
-}
-
void OutgoingMessage::convert(const qpid::messaging::Message& from)
{
//TODO: need to avoid copying as much as possible
- if (from.getContent().isList()) {
- encode<ListCodec>(from, message);
- } else if (from.getContent().isMap()) {
- encode<MapCodec>(from, message);
- } else {
- message.setData(from.getBytes());
- message.getMessageProperties().setContentType(from.getContentType());
- }
+ message.setData(from.getContent());
+ message.getMessageProperties().setContentType(from.getContentType());
const Address& address = from.getReplyTo();
if (!address.value.empty()) {
message.getMessageProperties().setReplyTo(AddressResolution::convert(address));
diff --git a/cpp/src/qpid/messaging/ListContent.cpp b/cpp/src/qpid/messaging/ListContent.cpp
new file mode 100644
index 0000000000..0c3ca5fc62
--- /dev/null
+++ b/cpp/src/qpid/messaging/ListContent.cpp
@@ -0,0 +1,98 @@
+/*
+ *
+ * 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/messaging/ListContent.h"
+#include "qpid/messaging/Message.h"
+#include "qpid/client/amqp0_10/Codecs.h"
+
+namespace qpid {
+namespace messaging {
+
+class ListContentImpl : public Variant
+{
+ Message* msg;
+ public:
+ ListContentImpl(Message& m) : Variant(Variant::List()), msg(&m)
+ {
+ if (msg->getContent().size()) {
+ qpid::client::amqp0_10::ListCodec codec;
+ codec.decode(msg->getContent(), *this);
+ }
+ }
+
+ void encode()
+ {
+ qpid::client::amqp0_10::ListCodec codec;
+ codec.encode(*this, msg->getContent());
+ }
+};
+
+ListContent::ListContent(Message& m) : impl(new ListContentImpl(m)) {}
+ListContent::~ListContent() { delete impl; }
+ListContent& ListContent::operator=(const ListContent& l) { *impl = *l.impl; return *this; }
+
+ListContent::const_iterator ListContent::begin() const { return impl->asList().begin(); }
+ListContent::const_iterator ListContent::end() const { return impl->asList().end(); }
+ListContent::const_reverse_iterator ListContent::rbegin() const { return impl->asList().rbegin(); }
+ListContent::const_reverse_iterator ListContent::rend() const { return impl->asList().rend(); }
+
+ListContent::iterator ListContent::begin() { return impl->asList().begin(); }
+ListContent::iterator ListContent::end() { return impl->asList().end(); }
+ListContent::reverse_iterator ListContent::rbegin() { return impl->asList().rbegin(); }
+ListContent::reverse_iterator ListContent::rend() { return impl->asList().rend(); }
+
+bool ListContent::empty() const { return impl->asList().empty(); }
+size_t ListContent::size() const { return impl->asList().size(); }
+
+const Variant& ListContent::front() const { return impl->asList().front(); }
+Variant& ListContent::front() { return impl->asList().front(); }
+const Variant& ListContent::back() const { return impl->asList().back(); }
+Variant& ListContent::back() { return impl->asList().back(); }
+
+void ListContent::push_front(const Variant& v) { impl->asList().push_front(v); }
+void ListContent::push_back(const Variant& v) { impl->asList().push_back(v); }
+
+void ListContent::pop_front() { impl->asList().pop_front(); }
+void ListContent::pop_back() { impl->asList().pop_back(); }
+
+ListContent::iterator ListContent::insert(iterator position, const Variant& v)
+{
+ return impl->asList().insert(position, v);
+}
+void ListContent::insert(iterator position, size_t n, const Variant& v)
+{
+ impl->asList().insert(position, n, v);
+}
+ListContent::iterator ListContent::erase(iterator position) { return impl->asList().erase(position); }
+ListContent::iterator ListContent::erase(iterator first, iterator last) { return impl->asList().erase(first, last); }
+void ListContent::clear() { impl->asList().clear(); }
+
+void ListContent::encode() { impl->encode(); }
+
+const Variant::List& ListContent::asList() const { return impl->asList(); }
+Variant::List& ListContent::asList() { return impl->asList(); }
+
+std::ostream& operator<<(std::ostream& out, const ListContent& m)
+{
+ out << m.asList();
+ return out;
+}
+
+}} // namespace qpid::messaging
diff --git a/cpp/src/qpid/messaging/ListView.cpp b/cpp/src/qpid/messaging/ListView.cpp
new file mode 100644
index 0000000000..b717d157fa
--- /dev/null
+++ b/cpp/src/qpid/messaging/ListView.cpp
@@ -0,0 +1,63 @@
+/*
+ *
+ * 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/messaging/ListView.h"
+#include "qpid/messaging/Message.h"
+#include "qpid/client/amqp0_10/Codecs.h"
+
+namespace qpid {
+namespace messaging {
+
+class ListViewImpl : public Variant
+{
+ public:
+ ListViewImpl(const Message& msg) : Variant(Variant::List())
+ {
+ if (msg.getContent().size()) {
+ qpid::client::amqp0_10::ListCodec codec;
+ codec.decode(msg.getContent(), *this);
+ }
+ }
+};
+
+ListView::ListView(const Message& m) :impl(new ListViewImpl(m)) {}
+ListView::~ListView() { delete impl; }
+ListView& ListView::operator=(const ListView& l) { *impl = *l.impl; return *this; }
+
+ListView::const_iterator ListView::begin() const { return impl->asList().begin(); }
+ListView::const_iterator ListView::end() const { return impl->asList().end(); }
+ListView::const_reverse_iterator ListView::rbegin() const { return impl->asList().rbegin(); }
+ListView::const_reverse_iterator ListView::rend() const { return impl->asList().rend(); }
+
+bool ListView::empty() const { return impl->asList().empty(); }
+size_t ListView::size() const { return impl->asList().size(); }
+
+const Variant& ListView::front() const { return impl->asList().front(); }
+const Variant& ListView::back() const { return impl->asList().back(); }
+
+const Variant::List& ListView::asList() const { return impl->asList(); }
+
+std::ostream& operator<<(std::ostream& out, const ListView& m)
+{
+ out << m.asList();
+ return out;
+}
+
+}} // namespace qpid::messaging
diff --git a/cpp/src/qpid/messaging/MapContent.cpp b/cpp/src/qpid/messaging/MapContent.cpp
new file mode 100644
index 0000000000..c653561fc9
--- /dev/null
+++ b/cpp/src/qpid/messaging/MapContent.cpp
@@ -0,0 +1,87 @@
+/*
+ *
+ * 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/messaging/MapContent.h"
+#include "qpid/messaging/Message.h"
+#include "qpid/client/amqp0_10/Codecs.h"
+
+namespace qpid {
+namespace messaging {
+
+class MapContentImpl : public Variant
+{
+ Message* msg;
+ public:
+ MapContentImpl(Message& m) : Variant(Variant::Map()), msg(&m)
+ {
+ if (msg->getContent().size()) {
+ qpid::client::amqp0_10::MapCodec codec;
+ codec.decode(msg->getContent(), *this);
+ }
+ }
+
+ void encode()
+ {
+ qpid::client::amqp0_10::MapCodec codec;
+ codec.encode(*this, msg->getContent());
+ }
+};
+
+MapContent::MapContent(Message& m) : impl(new MapContentImpl(m)) {}
+MapContent::~MapContent() { delete impl; }
+MapContent& MapContent::operator=(const MapContent& m) { *impl = *m.impl; return *this; }
+
+MapContent::const_iterator MapContent::begin() const { return impl->asMap().begin(); }
+MapContent::const_iterator MapContent::end() const { return impl->asMap().end(); }
+MapContent::const_reverse_iterator MapContent::rbegin() const { return impl->asMap().rbegin(); }
+MapContent::const_reverse_iterator MapContent::rend() const { return impl->asMap().rend(); }
+MapContent::iterator MapContent::begin() { return impl->asMap().begin(); }
+MapContent::iterator MapContent::end() { return impl->asMap().end(); }
+MapContent::reverse_iterator MapContent::rbegin() { return impl->asMap().rbegin(); }
+MapContent::reverse_iterator MapContent::rend() { return impl->asMap().rend(); }
+
+bool MapContent::empty() const { return impl->asMap().empty(); }
+size_t MapContent::size() const { return impl->asMap().size(); }
+
+MapContent::const_iterator MapContent::find(const key_type& key) const { return impl->asMap().find(key); }
+MapContent::iterator MapContent::find(const key_type& key) { return impl->asMap().find(key); }
+const Variant& MapContent::operator[](const key_type& key) const { return impl->asMap()[key]; }
+Variant& MapContent::operator[](const key_type& key) { return impl->asMap()[key]; }
+
+std::pair<MapContent::iterator,bool> MapContent::insert(const value_type& item) { return impl->asMap().insert(item); }
+MapContent::iterator MapContent::insert(iterator position, const value_type& item) { return impl->asMap().insert(position, item); }
+void MapContent::erase(iterator position) { impl->asMap().erase(position); }
+void MapContent::erase(iterator first, iterator last) { impl->asMap().erase(first, last); }
+size_t MapContent::erase(const key_type& key) { return impl->asMap().erase(key); }
+void MapContent::clear() { impl->asMap().clear(); }
+
+void MapContent::encode() { impl->encode(); }
+
+const std::map<MapContent::key_type, Variant>& MapContent::asMap() const { return impl->asMap(); }
+std::map<MapContent::key_type, Variant>& MapContent::asMap() { return impl->asMap(); }
+
+
+std::ostream& operator<<(std::ostream& out, const MapContent& m)
+{
+ out << m.asMap();
+ return out;
+}
+
+}} // namespace qpid::messaging
diff --git a/cpp/src/qpid/messaging/MapView.cpp b/cpp/src/qpid/messaging/MapView.cpp
new file mode 100644
index 0000000000..ffa6e91a16
--- /dev/null
+++ b/cpp/src/qpid/messaging/MapView.cpp
@@ -0,0 +1,63 @@
+/*
+ *
+ * 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/messaging/MapView.h"
+#include "qpid/messaging/Message.h"
+#include "qpid/client/amqp0_10/Codecs.h"
+
+namespace qpid {
+namespace messaging {
+
+class MapViewImpl : public Variant
+{
+ public:
+ MapViewImpl(const Message& msg) : Variant(Variant::Map())
+ {
+ if (msg.getContent().size()) {
+ qpid::client::amqp0_10::MapCodec codec;
+ codec.decode(msg.getContent(), *this);
+ }
+ }
+};
+
+MapView::MapView(const Message& m) : impl(new MapViewImpl(m)) {}
+MapView::~MapView() { delete impl; }
+MapView& MapView::operator=(const MapView& m) { *impl = *m.impl; return *this; }
+
+MapView::const_iterator MapView::begin() const { return impl->asMap().begin(); }
+MapView::const_iterator MapView::end() const { return impl->asMap().end(); }
+MapView::const_reverse_iterator MapView::rbegin() const { return impl->asMap().rbegin(); }
+MapView::const_reverse_iterator MapView::rend() const { return impl->asMap().rend(); }
+
+bool MapView::empty() const { return impl->asMap().empty(); }
+size_t MapView::size() const { return impl->asMap().size(); }
+
+MapView::const_iterator MapView::find(const key_type& key) const { return impl->asMap().find(key); }
+const Variant& MapView::operator[](const key_type& key) const { return impl->asMap()[key]; }
+
+const std::map<MapView::key_type, Variant>& MapView::asMap() const { return impl->asMap(); }
+
+std::ostream& operator<<(std::ostream& out, const MapView& m)
+{
+ out << m.asMap();
+ return out;
+}
+
+}} // namespace qpid::messaging
diff --git a/cpp/src/qpid/messaging/Message.cpp b/cpp/src/qpid/messaging/Message.cpp
index 1d844b3027..fb4e800eaa 100644
--- a/cpp/src/qpid/messaging/Message.cpp
+++ b/cpp/src/qpid/messaging/Message.cpp
@@ -27,7 +27,7 @@ namespace messaging {
Message::Message(const std::string& bytes) : impl(new MessageImpl(bytes)) {}
Message::Message(const char* bytes, size_t count) : impl(new MessageImpl(bytes, count)) {}
-Message::Message(const Message& m) : impl(new MessageImpl(m.getBytes())) {}
+Message::Message(const Message& m) : impl(new MessageImpl(m.getContent())) {}
Message::~Message() { delete impl; }
Message& Message::operator=(const Message& m) { *impl = *m.impl; return *this; }
@@ -44,27 +44,15 @@ const std::string& Message::getContentType() const { return impl->getContentType
const VariantMap& Message::getHeaders() const { return impl->getHeaders(); }
VariantMap& Message::getHeaders() { return impl->getHeaders(); }
-void Message::setBytes(const std::string& c) { impl->setBytes(c); }
-void Message::setBytes(const char* chars, size_t count) { impl->setBytes(chars, count); }
-const std::string& Message::getBytes() const { return impl->getBytes(); }
-std::string& Message::getBytes() { return impl->getBytes(); }
+void Message::setContent(const std::string& c) { impl->setBytes(c); }
+void Message::setContent(const char* chars, size_t count) { impl->setBytes(chars, count); }
+const std::string& Message::getContent() const { return impl->getBytes(); }
+std::string& Message::getContent() { return impl->getBytes(); }
-const char* Message::getRawContent() const { return impl->getBytes().data(); }
-size_t Message::getContentSize() const { return impl->getBytes().size(); }
-
-MessageContent& Message::getContent() { return *impl; }
-const MessageContent& Message::getContent() const { return *impl; }
-void Message::setContent(const std::string& s) { *impl = s; }
-void Message::setContent(const Variant::Map& m) { *impl = m; }
-void Message::setContent(const Variant::List& l) { *impl = l; }
-
-void Message::encode(Codec& codec) { impl->encode(codec); }
-
-void Message::decode(Codec& codec) { impl->decode(codec); }
-
-std::ostream& operator<<(std::ostream& out, const MessageContent& content)
+void Message::getContent(std::pair<const char*, size_t>& content) const
{
- return content.print(out);
+ content.first = impl->getBytes().data();
+ content.second = impl->getBytes().size();
}
}} // namespace qpid::messaging
diff --git a/cpp/src/qpid/messaging/MessageImpl.cpp b/cpp/src/qpid/messaging/MessageImpl.cpp
index 5df9218e03..e17fccd64f 100644
--- a/cpp/src/qpid/messaging/MessageImpl.cpp
+++ b/cpp/src/qpid/messaging/MessageImpl.cpp
@@ -28,8 +28,8 @@ namespace {
const std::string EMPTY_STRING = "";
}
-MessageImpl::MessageImpl(const std::string& c) : bytes(c), type(VAR_VOID), internalId(0) {}
-MessageImpl::MessageImpl(const char* chars, size_t count) : bytes(chars, count), type(VAR_VOID), internalId(0) {}
+MessageImpl::MessageImpl(const std::string& c) : bytes(c), internalId(0) {}
+MessageImpl::MessageImpl(const char* chars, size_t count) : bytes(chars, count), internalId(0) {}
void MessageImpl::setReplyTo(const Address& d) { replyTo = d; }
const Address& MessageImpl::getReplyTo() const { return replyTo; }
@@ -44,155 +44,14 @@ const VariantMap& MessageImpl::getHeaders() const { return headers; }
VariantMap& MessageImpl::getHeaders() { return headers; }
//should these methods be on MessageContent?
-void MessageImpl::setBytes(const std::string& c) { clear(); bytes = c; }
-void MessageImpl::setBytes(const char* chars, size_t count) { clear(); bytes.assign(chars, count); }
+void MessageImpl::setBytes(const std::string& c) { bytes = c; }
+void MessageImpl::setBytes(const char* chars, size_t count) { bytes.assign(chars, count); }
const std::string& MessageImpl::getBytes() const { return bytes; }
std::string& MessageImpl::getBytes() { return bytes; }
-
-Variant& MessageImpl::operator[](const std::string& key) { return asMap()[key]; }
-
-std::ostream& MessageImpl::print(std::ostream& out) const
-{
- if (type == VAR_MAP) {
- return out << content.asMap();
- } else if (type == VAR_LIST) {
- return out << content.asList();
- } else {
- return out << bytes;
- }
-}
-
-template <class T> MessageContent& MessageImpl::append(T& t)
-{
- if (type == VAR_VOID) {
- //TODO: this is inefficient, probably want to hold on to the stream object
- std::stringstream s;
- s << bytes;
- s << t;
- bytes = s.str();
- } else if (type == VAR_LIST) {
- content.asList().push_back(Variant(t));
- } else {
- throw InvalidConversion("<< operator only valid on strings and lists");
- }
- return *this;
-}
-
-MessageContent& MessageImpl::operator<<(const std::string& v) { return append(v); }
-MessageContent& MessageImpl::operator<<(const char* v) { return append(v); }
-MessageContent& MessageImpl::operator<<(bool v) { return append(v); }
-MessageContent& MessageImpl::operator<<(int8_t v) { return append(v); }
-MessageContent& MessageImpl::operator<<(int16_t v) { return append(v); }
-MessageContent& MessageImpl::operator<<(int32_t v) { return append(v); }
-MessageContent& MessageImpl::operator<<(int64_t v) { return append(v); }
-MessageContent& MessageImpl::operator<<(uint8_t v) { return append(v); }
-MessageContent& MessageImpl::operator<<(uint16_t v) { return append(v); }
-MessageContent& MessageImpl::operator<<(uint32_t v) { return append(v); }
-MessageContent& MessageImpl::operator<<(uint64_t v) { return append(v); }
-MessageContent& MessageImpl::operator<<(double v) { return append(v); }
-MessageContent& MessageImpl::operator<<(float v) { return append(v); }
-MessageContent& MessageImpl::operator=(const std::string& s)
-{
- type = VAR_VOID;
- bytes = s;
- return *this;
-}
-MessageContent& MessageImpl::operator=(const char* c)
-{
- type = VAR_VOID;
- bytes = c;
- return *this;
-}
-MessageContent& MessageImpl::operator=(const Variant::Map& m)
-{
- type = VAR_MAP;
- content = m;
- return *this;
-}
-
-MessageContent& MessageImpl::operator=(const Variant::List& l)
-{
- type = VAR_LIST;
- content = l;
- return *this;
-}
-
-void MessageImpl::encode(Codec& codec)
-{
- if (content.getType() != VAR_VOID) {
- bytes = EMPTY_STRING;
- codec.encode(content, bytes);
- }
-}
-
-void MessageImpl::getEncodedContent(Codec& codec, std::string& out) const
-{
- if (content.getType() != VAR_VOID) {
- codec.encode(content, out);
- } else {
- out = bytes;
- }
-}
-
-void MessageImpl::decode(Codec& codec)
-{
- codec.decode(bytes, content);
- if (content.getType() == VAR_MAP) type = VAR_MAP;
- else if (content.getType() == VAR_LIST) type = VAR_LIST;
- else type = VAR_VOID;//TODO: what if codec set some type other than map or list??
-}
-
void MessageImpl::setInternalId(qpid::framing::SequenceNumber i) { internalId = i; }
qpid::framing::SequenceNumber MessageImpl::getInternalId() { return internalId; }
-bool MessageImpl::isVoid() const { return type == VAR_VOID; }
-
-const std::string& MessageImpl::asString() const
-{
- if (isVoid()) return getBytes();
- else return content.getString();//will throw an error
-}
-std::string& MessageImpl::asString()
-{
- if (isVoid()) return getBytes();
- else return content.getString();//will throw an error
-}
-
-const char* MessageImpl::asChars() const
-{
- if (!isVoid()) throw InvalidConversion("Content is of structured type.");
- return bytes.data();
-}
-size_t MessageImpl::size() const
-{
- return bytes.size();
-}
-
-const Variant::Map& MessageImpl::asMap() const { return content.asMap(); }
-Variant::Map& MessageImpl::asMap()
-{
- if (isVoid()) {
- content = Variant::Map();
- type = VAR_MAP;
- }
- return content.asMap();
-}
-bool MessageImpl::isMap() const { return type == VAR_MAP; }
-
-const Variant::List& MessageImpl::asList() const { return content.asList(); }
-Variant::List& MessageImpl::asList()
-{
- if (isVoid()) {
- content = Variant::List();
- type = VAR_LIST;
- }
- return content.asList();
-}
-bool MessageImpl::isList() const { return type == VAR_LIST; }
-
-void MessageImpl::clear() { bytes = EMPTY_STRING; content.reset(); type = VAR_VOID; }
-
MessageImpl& MessageImplAccess::get(Message& msg)
{
return *msg.impl;
diff --git a/cpp/src/qpid/messaging/MessageImpl.h b/cpp/src/qpid/messaging/MessageImpl.h
index 1173e7570a..4939cdc5cc 100644
--- a/cpp/src/qpid/messaging/MessageImpl.h
+++ b/cpp/src/qpid/messaging/MessageImpl.h
@@ -22,15 +22,13 @@
*
*/
#include "qpid/messaging/Address.h"
-#include "qpid/messaging/Codec.h"
-#include "qpid/messaging/MessageContent.h"
#include "qpid/messaging/Variant.h"
#include "qpid/framing/SequenceNumber.h"
namespace qpid {
namespace messaging {
-struct MessageImpl : MessageContent
+struct MessageImpl
{
Address replyTo;
std::string subject;
@@ -38,8 +36,6 @@ struct MessageImpl : MessageContent
Variant::Map headers;
std::string bytes;
- Variant content;//used only for LIST and MAP
- VariantType type;//if LIST, MAP content holds the value; if VOID bytes holds the value
qpid::framing::SequenceNumber internalId;
@@ -66,54 +62,6 @@ struct MessageImpl : MessageContent
void setInternalId(qpid::framing::SequenceNumber id);
qpid::framing::SequenceNumber getInternalId();
- bool isVoid() const;
-
- const std::string& asString() const;
- std::string& asString();
-
- const char* asChars() const;
- size_t size() const;
-
- const Variant::Map& asMap() const;
- Variant::Map& asMap();
- bool isMap() const;
-
- const Variant::List& asList() const;
- Variant::List& asList();
- bool isList() const;
-
- void clear();
-
- void getEncodedContent(Codec& codec, std::string&) const;
- void encode(Codec& codec);
- void decode(Codec& codec);
-
- Variant& operator[](const std::string&);
-
- std::ostream& print(std::ostream& out) const;
-
- //operator<< for variety of types...
- MessageContent& operator<<(const std::string&);
- MessageContent& operator<<(const char*);
- MessageContent& operator<<(bool);
- MessageContent& operator<<(int8_t);
- MessageContent& operator<<(int16_t);
- MessageContent& operator<<(int32_t);
- MessageContent& operator<<(int64_t);
- MessageContent& operator<<(uint8_t);
- MessageContent& operator<<(uint16_t);
- MessageContent& operator<<(uint32_t);
- MessageContent& operator<<(uint64_t);
- MessageContent& operator<<(double);
- MessageContent& operator<<(float);
-
- //assignment from string, map and list
- MessageContent& operator=(const std::string&);
- MessageContent& operator=(const char*);
- MessageContent& operator=(const Variant::Map&);
- MessageContent& operator=(const Variant::List&);
-
- template <class T> MessageContent& append(T& t);
};
class Message;
diff --git a/cpp/src/tests/MessagingSessionTests.cpp b/cpp/src/tests/MessagingSessionTests.cpp
index f5a5420d3a..206f5ba691 100644
--- a/cpp/src/tests/MessagingSessionTests.cpp
+++ b/cpp/src/tests/MessagingSessionTests.cpp
@@ -22,6 +22,10 @@
#include "test_tools.h"
#include "BrokerFixture.h"
#include "qpid/messaging/Connection.h"
+#include "qpid/messaging/ListContent.h"
+#include "qpid/messaging/ListView.h"
+#include "qpid/messaging/MapContent.h"
+#include "qpid/messaging/MapView.h"
#include "qpid/messaging/Message.h"
#include "qpid/messaging/MessageListener.h"
#include "qpid/messaging/Receiver.h"
@@ -160,7 +164,7 @@ struct MessageDataCollector : MessageListener
std::vector<std::string> messageData;
void received(Message& message) {
- messageData.push_back(message.getBytes());
+ messageData.push_back(message.getContent());
}
};
@@ -169,7 +173,7 @@ std::vector<std::string> fetch(Receiver& receiver, int count, qpid::sys::Duratio
std::vector<std::string> data;
Message message;
for (int i = 0; i < count && receiver.fetch(message, timeout); i++) {
- data.push_back(message.getBytes());
+ data.push_back(message.getContent());
}
return data;
}
@@ -183,7 +187,7 @@ QPID_AUTO_TEST_CASE(testSimpleSendReceive)
Receiver receiver = fix.session.createReceiver(fix.queue);
Message in = receiver.fetch(5 * qpid::sys::TIME_SEC);
fix.session.acknowledge();
- BOOST_CHECK_EQUAL(in.getBytes(), out.getBytes());
+ BOOST_CHECK_EQUAL(in.getContent(), out.getContent());
}
QPID_AUTO_TEST_CASE(testSendReceiveHeaders)
@@ -199,7 +203,7 @@ QPID_AUTO_TEST_CASE(testSendReceiveHeaders)
Message in;
for (uint i = 0; i < 10; ++i) {
BOOST_CHECK(receiver.fetch(in, 5 * qpid::sys::TIME_SEC));
- BOOST_CHECK_EQUAL(in.getBytes(), out.getBytes());
+ BOOST_CHECK_EQUAL(in.getContent(), out.getContent());
BOOST_CHECK_EQUAL(in.getHeaders()["a"].asUint32(), i);
fix.session.acknowledge();
}
@@ -229,22 +233,22 @@ QPID_AUTO_TEST_CASE(testSimpleTopic)
Receiver sub1 = fix.session.createReceiver(fix.topic);
sub1.setCapacity(10u);
sub1.start();
- msg.setBytes("two");
+ msg.setContent("two");
sender.send(msg);
Receiver sub2 = fix.session.createReceiver(fix.topic);
sub2.setCapacity(10u);
sub2.start();
- msg.setBytes("three");
+ msg.setContent("three");
sender.send(msg);
Receiver sub3 = fix.session.createReceiver(fix.topic);
sub3.setCapacity(10u);
sub3.start();
- msg.setBytes("four");
+ msg.setContent("four");
sender.send(msg);
BOOST_CHECK_EQUAL(fetch(sub2, 2), boost::assign::list_of<std::string>("three")("four"));
sub2.cancel();
- msg.setBytes("five");
+ msg.setContent("five");
sender.send(msg);
BOOST_CHECK_EQUAL(fetch(sub1, 4), boost::assign::list_of<std::string>("two")("three")("four")("five"));
BOOST_CHECK_EQUAL(fetch(sub3, 2), boost::assign::list_of<std::string>("four")("five"));
@@ -274,7 +278,7 @@ QPID_AUTO_TEST_CASE(testSessionFetch)
for (uint i = 0; i < fix.queues.size(); i++) {
Message msg;
BOOST_CHECK(fix.session.fetch(msg, qpid::sys::TIME_SEC));
- BOOST_CHECK_EQUAL(msg.getBytes(), (boost::format("Message_%1%") % (i+1)).str());
+ BOOST_CHECK_EQUAL(msg.getContent(), (boost::format("Message_%1%") % (i+1)).str());
}
}
@@ -307,13 +311,16 @@ QPID_AUTO_TEST_CASE(testMapMessage)
QueueFixture fix;
Sender sender = fix.session.createSender(fix.queue);
Message out;
- out.getContent().asMap()["abc"] = "def";
- out.getContent().asMap()["pi"] = 3.14f;
+ MapContent content(out);
+ content["abc"] = "def";
+ content["pi"] = 3.14f;
+ content.encode();
sender.send(out);
Receiver receiver = fix.session.createReceiver(fix.queue);
Message in = receiver.fetch(5 * qpid::sys::TIME_SEC);
- BOOST_CHECK_EQUAL(in.getContent().asMap()["abc"].asString(), "def");
- BOOST_CHECK_EQUAL(in.getContent().asMap()["pi"].asFloat(), 3.14f);
+ MapView view(in);
+ BOOST_CHECK_EQUAL(view["abc"].asString(), "def");
+ BOOST_CHECK_EQUAL(view["pi"].asFloat(), 3.14f);
fix.session.acknowledge();
}
@@ -322,23 +329,31 @@ QPID_AUTO_TEST_CASE(testListMessage)
QueueFixture fix;
Sender sender = fix.session.createSender(fix.queue);
Message out;
- out.getContent() = Variant::List();
- out.getContent() << "abc";
- out.getContent() << 1234;
- out.getContent() << "def";
- out.getContent() << 56.789;
+ ListContent content(out);
+ content.push_back(Variant("abc"));
+ content.push_back(Variant(1234));
+ content.push_back(Variant("def"));
+ content.push_back(Variant(56.789));
+ content.encode();
sender.send(out);
Receiver receiver = fix.session.createReceiver(fix.queue);
Message in = receiver.fetch(5 * qpid::sys::TIME_SEC);
- Variant::List& list = in.getContent().asList();
- BOOST_CHECK_EQUAL(list.size(), out.getContent().asList().size());
- BOOST_CHECK_EQUAL(list.front().asString(), "abc");
- list.pop_front();
- BOOST_CHECK_EQUAL(list.front().asInt64(), 1234);
- list.pop_front();
- BOOST_CHECK_EQUAL(list.front().asString(), "def");
- list.pop_front();
- BOOST_CHECK_EQUAL(list.front().asDouble(), 56.789);
+ ListView view(in);
+ BOOST_CHECK_EQUAL(view.size(), content.size());
+ BOOST_CHECK_EQUAL(view.front().asString(), "abc");
+ BOOST_CHECK_EQUAL(view.back().asDouble(), 56.789);
+
+ ListView::const_iterator i = view.begin();
+ BOOST_CHECK(i != view.end());
+ BOOST_CHECK_EQUAL(i->asString(), "abc");
+ BOOST_CHECK(++i != view.end());
+ BOOST_CHECK_EQUAL(i->asInt64(), 1234);
+ BOOST_CHECK(++i != view.end());
+ BOOST_CHECK_EQUAL(i->asString(), "def");
+ BOOST_CHECK(++i != view.end());
+ BOOST_CHECK_EQUAL(i->asDouble(), 56.789);
+ BOOST_CHECK(++i == view.end());
+
fix.session.acknowledge();
}
@@ -352,10 +367,10 @@ QPID_AUTO_TEST_CASE(testReject)
sender.send(m2);
Receiver receiver = fix.session.createReceiver(fix.queue);
Message in = receiver.fetch(5 * qpid::sys::TIME_SEC);
- BOOST_CHECK_EQUAL(in.getBytes(), m1.getBytes());
+ BOOST_CHECK_EQUAL(in.getContent(), m1.getContent());
fix.session.reject(in);
in = receiver.fetch(5 * qpid::sys::TIME_SEC);
- BOOST_CHECK_EQUAL(in.getBytes(), m2.getBytes());
+ BOOST_CHECK_EQUAL(in.getContent(), m2.getContent());
fix.session.acknowledge();
}
@@ -384,15 +399,15 @@ QPID_AUTO_TEST_CASE(testAvailable)
for (uint i = 0; i < 5; ++i) {
BOOST_CHECK_EQUAL(fix.session.available(), 15u - 2*i);
BOOST_CHECK_EQUAL(r1.available(), 10u - i);
- BOOST_CHECK_EQUAL(r1.fetch().getBytes(), (boost::format("A_%1%") % (i+1)).str());
+ BOOST_CHECK_EQUAL(r1.fetch().getContent(), (boost::format("A_%1%") % (i+1)).str());
BOOST_CHECK_EQUAL(r2.available(), 5u - i);
- BOOST_CHECK_EQUAL(r2.fetch().getBytes(), (boost::format("B_%1%") % (i+1)).str());
+ BOOST_CHECK_EQUAL(r2.fetch().getContent(), (boost::format("B_%1%") % (i+1)).str());
fix.session.acknowledge();
}
for (uint i = 5; i < 10; ++i) {
BOOST_CHECK_EQUAL(fix.session.available(), 10u - i);
BOOST_CHECK_EQUAL(r1.available(), 10u - i);
- BOOST_CHECK_EQUAL(r1.fetch().getBytes(), (boost::format("A_%1%") % (i+1)).str());
+ BOOST_CHECK_EQUAL(r1.fetch().getContent(), (boost::format("A_%1%") % (i+1)).str());
}
}
@@ -405,7 +420,7 @@ QPID_AUTO_TEST_CASE(testPendingAck)
}
Receiver receiver = fix.session.createReceiver(fix.queue);
for (uint i = 0; i < 10; ++i) {
- BOOST_CHECK_EQUAL(receiver.fetch().getBytes(), (boost::format("Message_%1%") % (i+1)).str());
+ BOOST_CHECK_EQUAL(receiver.fetch().getContent(), (boost::format("Message_%1%") % (i+1)).str());
}
BOOST_CHECK_EQUAL(fix.session.pendingAck(), 0u);
fix.session.acknowledge();
@@ -431,7 +446,7 @@ QPID_AUTO_TEST_CASE(testPendingSend)
Receiver receiver = fix.session.createReceiver(fix.queue);
for (uint i = 0; i < 10; ++i) {
- BOOST_CHECK_EQUAL(receiver.fetch().getBytes(), (boost::format("Message_%1%") % (i+1)).str());
+ BOOST_CHECK_EQUAL(receiver.fetch().getContent(), (boost::format("Message_%1%") % (i+1)).str());
}
fix.session.acknowledge();
}