You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by as...@apache.org on 2017/06/02 22:51:17 UTC
[03/20] qpid-proton git commit: PROTON-1288: c++ hide proton::message
implementation details
PROTON-1288: c++ hide proton::message implementation details
Hide extra book-keeping types in extra storage allocated with the pn_message_t.
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/48a5e47a
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/48a5e47a
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/48a5e47a
Branch: refs/heads/PROTON-1488
Commit: 48a5e47a09268ddb19f925d8f66301718f42b87a
Parents: 860b322
Author: Alan Conway <ac...@redhat.com>
Authored: Wed May 17 13:52:13 2017 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Wed May 24 14:38:25 2017 -0400
----------------------------------------------------------------------
.../bindings/cpp/include/proton/message.hpp | 6 +-
proton-c/bindings/cpp/src/message.cpp | 74 +++++++++++++-------
2 files changed, 52 insertions(+), 28 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/48a5e47a/proton-c/bindings/cpp/include/proton/message.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/message.hpp b/proton-c/bindings/cpp/include/proton/message.hpp
index ff60c99..faf2f29 100644
--- a/proton-c/bindings/cpp/include/proton/message.hpp
+++ b/proton-c/bindings/cpp/include/proton/message.hpp
@@ -321,13 +321,11 @@ class message {
/// @cond INTERNAL
private:
+ struct impl;
pn_message_t *pn_msg() const;
+ struct impl& impl() const;
mutable pn_message_t *pn_msg_;
- mutable value body_;
- mutable property_map application_properties_;
- mutable annotation_map message_annotations_;
- mutable annotation_map delivery_annotations_;
/// Decode the message corresponding to a delivery from a link.
void decode(proton::delivery);
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/48a5e47a/proton-c/bindings/cpp/src/message.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/message.cpp b/proton-c/bindings/cpp/src/message.cpp
index 59f8329..df7fae1 100644
--- a/proton-c/bindings/cpp/src/message.cpp
+++ b/proton-c/bindings/cpp/src/message.cpp
@@ -41,6 +41,32 @@
namespace proton {
+struct message::impl {
+ value body_;
+ property_map application_properties_;
+ annotation_map message_annotations_;
+ annotation_map delivery_annotations_;
+
+ impl(pn_message_t *msg) {
+ body_.reset(pn_message_body(msg));
+ }
+
+ void clear() {
+ application_properties_.clear();
+ message_annotations_.clear();
+ delivery_annotations_.clear();
+ }
+
+ friend void swap(impl& x, impl& y) {
+ using std::swap;
+ swap(x.body_, y.body_);
+ swap(x.application_properties_, y.application_properties_);
+ swap(x.message_annotations_, y.message_annotations_);
+ swap(x.delivery_annotations_, y.delivery_annotations_);
+ }
+};
+
+
message::message() : pn_msg_(0) {}
message::message(const message &m) : pn_msg_(0) { *this = m; }
@@ -55,28 +81,31 @@ message& message::operator=(message&& m) {
message::message(const value& x) : pn_msg_(0) { body() = x; }
message::~message() {
- // Workaround proton bug: Must release all refs to body before calling pn_message_free()
- body_.reset();
- pn_message_free(pn_msg_);
+ if (pn_msg_) {
+ impl().~impl(); // destroy in-place
+ pn_message_free(pn_msg_);
+ }
}
void swap(message& x, message& y) {
using std::swap;
swap(x.pn_msg_, y.pn_msg_);
- swap(x.body_, y.body_);
- swap(x.application_properties_, y.application_properties_);
- swap(x.message_annotations_, y.message_annotations_);
- swap(x.delivery_annotations_, y.delivery_annotations_);
+ swap(x.impl(), y.impl());
}
pn_message_t *message::pn_msg() const {
if (!pn_msg_) {
- pn_msg_ = pn_message();
- body_.reset(pn_message_body(pn_msg_));
+ pn_msg_ = pn_message_with_extra(sizeof(struct message::impl));
+ // Construct impl in extra storage allocated with pn_msg_
+ new (pn_message_get_extra(pn_msg_)) struct message::impl(pn_msg_);
}
return pn_msg_;
}
+struct message::impl& message::impl() const {
+ return *(struct message::impl*)pn_message_get_extra(pn_msg());
+}
+
message& message::operator=(const message& m) {
if (&m != this) {
// TODO aconway 2015-08-10: more efficient pn_message_copy function
@@ -209,8 +238,8 @@ void message::inferred(bool b) { pn_message_set_inferred(pn_msg(), b); }
void message::body(const value& x) { body() = x; }
-const value& message::body() const { pn_msg(); return body_; }
-value& message::body() { pn_msg(); return body_; }
+const value& message::body() const { return impl().body_; }
+value& message::body() { return impl().body_; }
// MAP CACHING: the properties and annotations maps can either be encoded in the
// pn_message pn_data_t structures OR decoded as C++ map members of the message
@@ -239,35 +268,35 @@ template<class M, class F> M& put_map(pn_message_t* msg, F get, M& map) {
}
message::property_map& message::properties() {
- return get_map(pn_msg(), pn_message_properties, application_properties_);
+ return get_map(pn_msg(), pn_message_properties, impl().application_properties_);
}
const message::property_map& message::properties() const {
- return get_map(pn_msg(), pn_message_properties, application_properties_);
+ return get_map(pn_msg(), pn_message_properties, impl().application_properties_);
}
message::annotation_map& message::message_annotations() {
- return get_map(pn_msg(), pn_message_annotations, message_annotations_);
+ return get_map(pn_msg(), pn_message_annotations, impl().message_annotations_);
}
const message::annotation_map& message::message_annotations() const {
- return get_map(pn_msg(), pn_message_annotations, message_annotations_);
+ return get_map(pn_msg(), pn_message_annotations, impl().message_annotations_);
}
message::annotation_map& message::delivery_annotations() {
- return get_map(pn_msg(), pn_message_instructions, delivery_annotations_);
+ return get_map(pn_msg(), pn_message_instructions, impl().delivery_annotations_);
}
const message::annotation_map& message::delivery_annotations() const {
- return get_map(pn_msg(), pn_message_instructions, delivery_annotations_);
+ return get_map(pn_msg(), pn_message_instructions, impl().delivery_annotations_);
}
void message::encode(std::vector<char> &s) const {
- put_map(pn_msg(), pn_message_properties, application_properties_);
- put_map(pn_msg(), pn_message_annotations, message_annotations_);
- put_map(pn_msg(), pn_message_instructions, delivery_annotations_);
+ put_map(pn_msg(), pn_message_properties, impl().application_properties_);
+ put_map(pn_msg(), pn_message_annotations, impl().message_annotations_);
+ put_map(pn_msg(), pn_message_instructions, impl().delivery_annotations_);
size_t sz = std::max(s.capacity(), size_t(512));
while (true) {
s.resize(sz);
@@ -293,10 +322,7 @@ std::vector<char> message::encode() const {
void message::decode(const std::vector<char> &s) {
if (s.empty())
throw error("message decode: no data");
- application_properties_.clear();
- message_annotations_.clear();
- delivery_annotations_.clear();
- assert(!s.empty());
+ impl().clear();
check(pn_message_decode(pn_msg(), &s[0], s.size()));
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org