You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ac...@apache.org on 2015/11/17 19:54:50 UTC

qpid-proton git commit: NO-JIRA: c++ add support for application properties and the inferred flag.

Repository: qpid-proton
Updated Branches:
  refs/heads/master f4b35515b -> 89923cf5b


NO-JIRA: c++ add support for application properties and the inferred flag.

Added message::message(const value&) to construct a message with an initial body value
Get rid of templated conversions, causing ambiguity.


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/89923cf5
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/89923cf5
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/89923cf5

Branch: refs/heads/master
Commit: 89923cf5bbf016df5fd82b84b29f92ec943fb050
Parents: f4b3551
Author: Alan Conway <ac...@redhat.com>
Authored: Mon Nov 16 15:06:40 2015 -0500
Committer: Alan Conway <ac...@redhat.com>
Committed: Tue Nov 17 13:50:21 2015 -0500

----------------------------------------------------------------------
 examples/cpp/encode_decode.cpp                  |  9 +-
 examples/cpp/helloworld.cpp                     |  3 +-
 examples/cpp/helloworld_blocking.cpp            |  3 +-
 examples/cpp/helloworld_direct.cpp              |  3 +-
 proton-c/bindings/cpp/CMakeLists.txt            |  1 +
 proton-c/bindings/cpp/include/proton/data.hpp   |  8 +-
 .../bindings/cpp/include/proton/decoder.hpp     |  5 +-
 .../bindings/cpp/include/proton/message.hpp     | 46 +++++++++-
 .../bindings/cpp/include/proton/message_id.hpp  |  6 +-
 .../cpp/include/proton/pn_unique_ptr.hpp        |  6 +-
 proton-c/bindings/cpp/include/proton/value.hpp  |  4 -
 proton-c/bindings/cpp/src/decoder.cpp           |  6 +-
 proton-c/bindings/cpp/src/message.cpp           | 58 +++++++++++++
 proton-c/bindings/cpp/src/message_test.cpp      | 89 ++++++++++++++++++++
 14 files changed, 221 insertions(+), 26 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/89923cf5/examples/cpp/encode_decode.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/encode_decode.cpp b/examples/cpp/encode_decode.cpp
index 3d6fe48..1ed8b64 100644
--- a/examples/cpp/encode_decode.cpp
+++ b/examples/cpp/encode_decode.cpp
@@ -71,7 +71,8 @@ void uniform_containers() {
     // By default a C++ container is encoded as an AMQP array.
     v = a;
     print(v);
-    std::list<int> a1 = v;          // Decode as a C++ std::list instead
+    std::list<int> a1;
+    v.get(a1);                  // Decode as a C++ std::list instead
     std::cout << a1 << std::endl;
 
     // You can specify that a container should be encoded as an AMQP list instead.
@@ -111,7 +112,8 @@ void mixed_containers() {
     // By default, a sequence of proton::value is treated as an AMQP list.
     v = l;
     print(v);
-    std::vector<proton::value> l2 = v;
+    std::vector<proton::value> l2;
+    v.get(l2);
     std::cout << l2 << std::endl;
 
     std::map<proton::value, proton::value> m;
@@ -119,7 +121,8 @@ void mixed_containers() {
     m[proton::value(4)] = proton::value("four");
     v = m;
     print(v);
-    std::map<proton::value, proton::value> m2 = v;
+    std::map<proton::value, proton::value> m2;
+    v.get(m2);
     std::cout << m2 << std::endl;
 }
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/89923cf5/examples/cpp/helloworld.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/helloworld.cpp b/examples/cpp/helloworld.cpp
index b1eed87..d6caa27 100644
--- a/examples/cpp/helloworld.cpp
+++ b/examples/cpp/helloworld.cpp
@@ -40,8 +40,7 @@ class hello_world : public proton::messaging_handler {
     }
 
     void on_sendable(proton::event &e) {
-        proton::message m;
-        m.body("Hello World!");
+        proton::message m("Hello World!");
         e.sender().send(m);
         e.sender().close();
     }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/89923cf5/examples/cpp/helloworld_blocking.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/helloworld_blocking.cpp b/examples/cpp/helloworld_blocking.cpp
index f054df2..81a56b9 100644
--- a/examples/cpp/helloworld_blocking.cpp
+++ b/examples/cpp/helloworld_blocking.cpp
@@ -34,8 +34,7 @@ int main(int argc, char **argv) {
         proton::blocking_receiver receiver(conn, url.path());
         proton::blocking_sender sender(conn, url.path());
 
-        proton::message m;
-        m.body("Hello World!");
+        proton::message m("Hello World!");
         sender.send(m);
 
         proton::duration timeout(30000);

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/89923cf5/examples/cpp/helloworld_direct.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/helloworld_direct.cpp b/examples/cpp/helloworld_direct.cpp
index b141f1b..d055fde 100644
--- a/examples/cpp/helloworld_direct.cpp
+++ b/examples/cpp/helloworld_direct.cpp
@@ -40,8 +40,7 @@ class hello_world_direct : public proton::messaging_handler {
     }
 
     void on_sendable(proton::event &e) {
-        proton::message m;
-        m.body("Hello World!");
+        proton::message m("Hello World!");
         e.sender().send(m);
         e.sender().close();
     }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/89923cf5/proton-c/bindings/cpp/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/CMakeLists.txt b/proton-c/bindings/cpp/CMakeLists.txt
index 3995c20..7660961 100644
--- a/proton-c/bindings/cpp/CMakeLists.txt
+++ b/proton-c/bindings/cpp/CMakeLists.txt
@@ -162,5 +162,6 @@ macro(add_cpp_test test)
 endmacro(add_cpp_test)
 
 add_cpp_test(interop_test ${CMAKE_SOURCE_DIR}/tests)
+add_cpp_test(message_test)
 add_cpp_test(conversion_test)
 add_cpp_test(encode_decode_test)

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/89923cf5/proton-c/bindings/cpp/include/proton/data.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/data.hpp b/proton-c/bindings/cpp/include/proton/data.hpp
index 21504a5..752765e 100644
--- a/proton-c/bindings/cpp/include/proton/data.hpp
+++ b/proton-c/bindings/cpp/include/proton/data.hpp
@@ -42,6 +42,7 @@ class data : public facade<pn_data_t, data, comparable<data> > {
     PN_CPP_EXTERN static pn_unique_ptr<data> create();
 
     PN_CPP_EXTERN data& operator=(const data&);
+
     template<class T> data& operator=(const T &t) {
         clear(); encoder() << t; decoder().rewind(); return *this;
     }
@@ -58,13 +59,12 @@ class data : public facade<pn_data_t, data, comparable<data> > {
     /** Decoder to decode from this value */
     PN_CPP_EXTERN class decoder& decoder();
 
-    /** Type of the current value*/
+    /** Rewind and return the type of the first value*/
     PN_CPP_EXTERN type_id type() const;
 
-    /** Get the first value, don't move the decoder pointer. */
-    template<class T> void get(T &t) const { decoder() >> t; decoder().backup(); }
+    /** Rewind and decode the first value */
+    template<class T> void get(T &t) const { decoder().rewind(); decoder() >> t; }
 
-    /** Get the first value, don't move the decoder pointer. */
     template<class T> T get() const { T t; get(t); return t; }
 
     PN_CPP_EXTERN bool operator==(const data& x) const;

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/89923cf5/proton-c/bindings/cpp/include/proton/decoder.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/decoder.hpp b/proton-c/bindings/cpp/include/proton/decoder.hpp
index 1258e5a..3da078c 100644
--- a/proton-c/bindings/cpp/include/proton/decoder.hpp
+++ b/proton-c/bindings/cpp/include/proton/decoder.hpp
@@ -173,6 +173,9 @@ class decoder : public facade<pn_data_t, decoder> {
     /** Rewind to the start of the data. */
     PN_CPP_EXTERN void rewind();
 
+    /** Skip one value */
+    PN_CPP_EXTERN void skip();
+
     /** Back up by one value */
     PN_CPP_EXTERN void backup();
 
@@ -250,7 +253,7 @@ class decoder : public facade<pn_data_t, decoder> {
     PN_CPP_EXTERN friend decoder& operator>>(decoder&, finish);
 
     /** Skip a value */
-    PN_CPP_EXTERN friend decoder& operator>>(decoder&, skip);
+    PN_CPP_EXTERN friend decoder& operator>>(decoder&, struct skip);
 
     /** Throw an exception if decoder.type() != assert_type.type */
     PN_CPP_EXTERN friend decoder& operator>>(decoder&, assert_type);

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/89923cf5/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 76bbc19..f68873b 100644
--- a/proton-c/bindings/cpp/include/proton/message.hpp
+++ b/proton-c/bindings/cpp/include/proton/message.hpp
@@ -46,6 +46,8 @@ class message
   public:
     PN_CPP_EXTERN message();
     PN_CPP_EXTERN message(const message&);
+    PN_CPP_EXTERN message(const value&);
+
 #if PN_HAS_CPP11
     PN_CPP_EXTERN message(message&&);
 #endif
@@ -57,7 +59,7 @@ class message
     /** Clear the message content and properties. */
     PN_CPP_EXTERN void clear();
 
-    ///@name Message properties
+    ///@name Standard AMQP properties
     ///@{
 
     PN_CPP_EXTERN void id(const message_id& id);
@@ -95,6 +97,7 @@ class message
 
     PN_CPP_EXTERN void reply_to_group_id(const std::string &s);
     PN_CPP_EXTERN std::string reply_to_group_id() const;
+
     ///@}
 
     /** Set the body. */
@@ -106,6 +109,30 @@ class message
     /** Get a reference to the body data, can be modified in-place. */
     PN_CPP_EXTERN data& body();
 
+    /** Set the application properties. Must be a map with string keys or an
+     * empty value. You can assign to a proton::value from a standard C++ map
+     * of std::string to proton::value.
+     */
+    PN_CPP_EXTERN void properties(const value&);
+
+    /** Get the application properties, which will be a map with string keys or
+     * an empty value. You can assign proton::value containing a map to a
+     * standard C++ map of std::string to proton::value.
+     */
+    PN_CPP_EXTERN const data& properties() const;
+
+    /** Get a reference to the application properties, can be modified in-place.*/
+    PN_CPP_EXTERN data& properties();
+
+    /** Set an individual application property. */
+    PN_CPP_EXTERN void property(const std::string &name, const value &);
+
+    /** Get an individual application property. Returns an empty value if not found. */
+    PN_CPP_EXTERN value property(const std::string &name) const;
+
+    /** Erase an application property. Returns false if there was no such property. */
+    PN_CPP_EXTERN bool erase_property(const std::string &name);
+
     /** Encode into a string, growing the string if necessary. */
     PN_CPP_EXTERN void encode(std::string &bytes) const;
 
@@ -118,6 +145,23 @@ class message
     /// Decode the message from link corresponding to delivery.
     PN_CPP_EXTERN void decode(proton::link&, proton::delivery&);
 
+    /**
+     * Get the inferred flag for a message.
+     *
+     * The inferred flag for a message indicates how the message content
+     * is encoded into AMQP sections. If inferred is true then binary and
+     * list values in the body of the message will be encoded as AMQP DATA
+     * and AMQP SEQUENCE sections, respectively. If inferred is false,
+     * then all values in the body of the message will be encoded as AMQP
+     * VALUE sections regardless of their type. Use
+     * ::pn_message_set_inferred to set the value.
+     *
+     * @param[in] msg a message object
+     * @return the value of the inferred flag for the message
+     */
+    PN_CPP_EXTERN bool inferred() const;
+    PN_CPP_EXTERN void inferred(bool);
+
   private:
     pn_message_t *message_;
 };

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/89923cf5/proton-c/bindings/cpp/include/proton/message_id.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/message_id.hpp b/proton-c/bindings/cpp/include/proton/message_id.hpp
index 4ff8b52..d6ce186 100644
--- a/proton-c/bindings/cpp/include/proton/message_id.hpp
+++ b/proton-c/bindings/cpp/include/proton/message_id.hpp
@@ -29,14 +29,13 @@ namespace proton {
 class message_id : public comparable<message_id> {
   public:
     message_id() {}
-    message_id(const value& x) : value_(x) {}
-    message_id(const data& x) : value_(x) {}
     message_id(const uint64_t& x) : value_(x) {}
     message_id(const amqp_uuid& x) : value_(x) {}
     message_id(const amqp_binary& x) : value_(x) {}
     message_id(const amqp_string& x) : value_(x) {}
     /// string is encoded as amqp_string
     message_id(const std::string& x) : value_(x) {}
+    message_id(const char *x) : value_(x) {}
 
     message_id& operator=(const message_id& x) { value_ = x.value_; return *this; }
     message_id& operator=(const uint64_t& x) { value_ = x; return *this; }
@@ -45,6 +44,7 @@ class message_id : public comparable<message_id> {
     message_id& operator=(const amqp_string& x) { value_ = x; return *this; }
     /// string is encoded as amqp_string
     message_id& operator=(const std::string& x) { value_ = x; return *this; }
+    message_id& operator=(const char *x) { value_ = x; return *this; }
 
     void clear() { value_.clear(); }
     bool empty() const { return value_.empty(); }
@@ -58,7 +58,6 @@ class message_id : public comparable<message_id> {
     void get(std::string& x) const { value_.get(x); }
 
     template<class T> T get() const { T x; get(x); return x; }
-    template<class T> operator T() const { return get<T>(); }
 
     // String representation: decimal representation of uint64_t, standard text
     // representation of UUID, amqp_string or amqp_binary are returned without
@@ -73,6 +72,7 @@ class message_id : public comparable<message_id> {
   friend PN_CPP_EXTERN decoder& operator>>(decoder&, message_id&);
 
   private:
+    message_id(const data& d) : value_(d) {}
     value value_;
   friend class message;
 };

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/89923cf5/proton-c/bindings/cpp/include/proton/pn_unique_ptr.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/pn_unique_ptr.hpp b/proton-c/bindings/cpp/include/proton/pn_unique_ptr.hpp
index b94667f..d63c8e5 100644
--- a/proton-c/bindings/cpp/include/proton/pn_unique_ptr.hpp
+++ b/proton-c/bindings/cpp/include/proton/pn_unique_ptr.hpp
@@ -46,9 +46,11 @@ template <class T> class pn_unique_ptr {
     T& operator*() const { return *ptr_; }
     T* operator->() const { return ptr_; }
     T* get() const { return ptr_; }
-    void swap(pn_unique_ptr<T>& x) { T *p = x.ptr_; x.ptr_ = ptr_; ptr_ = p; }
-    void reset(T* p = 0) { pn_unique_ptr<T> tmp(p); tmp.swap(*this); }
+    void swap(pn_unique_ptr<T>& x) { std::swap(ptr_, x.ptr_); }
+    void reset(T* p = 0) { pn_unique_ptr<T> tmp(p); swap(tmp); }
     T* release() { T *p = ptr_; ptr_ = 0; return p; }
+    operator bool() const { return get(); }
+    bool operator !() const { return get(); }
 
 #if PN_HAS_STD_PTR
     operator std::unique_ptr<T>() { T *p = ptr_; ptr_ = 0; return std::unique_ptr<T>(p); }

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/89923cf5/proton-c/bindings/cpp/include/proton/value.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/value.hpp b/proton-c/bindings/cpp/include/proton/value.hpp
index 39902dc..62b8a9e 100644
--- a/proton-c/bindings/cpp/include/proton/value.hpp
+++ b/proton-c/bindings/cpp/include/proton/value.hpp
@@ -71,9 +71,6 @@ class value : public comparable<value> {
     /** Get the value. */
     template<class T> T get() const { T t; get(t); return t; }
 
-    /** Automatic conversion */
-    template<class T> operator T() const { return get<T>(); }
-
     PN_CPP_EXTERN bool operator==(const value& x) const;
     PN_CPP_EXTERN bool operator<(const value& x) const;
 
@@ -83,7 +80,6 @@ class value : public comparable<value> {
 
   private:
     pn_unique_ptr<data> data_;
-  friend class message;
 };
 
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/89923cf5/proton-c/bindings/cpp/src/decoder.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/decoder.cpp b/proton-c/bindings/cpp/src/decoder.cpp
index 1fe13a2..cab7826 100644
--- a/proton-c/bindings/cpp/src/decoder.cpp
+++ b/proton-c/bindings/cpp/src/decoder.cpp
@@ -77,9 +77,11 @@ bool decoder::more() const {
     return pn_data_next(pn_cast(this));
 }
 
-void decoder::rewind() { ::pn_data_rewind(pn_cast(this)); }
+void decoder::rewind() { pn_data_rewind(pn_cast(this)); }
 
-void decoder::backup() { ::pn_data_prev(pn_cast(this)); }
+void decoder::backup() { pn_data_prev(pn_cast(this)); }
+
+void decoder::skip() { pn_data_next(pn_cast(this)); }
 
 data& decoder::data() { return *data::cast(pn_cast(this)); }
 

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/89923cf5/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 7ebb821..285771b 100644
--- a/proton-c/bindings/cpp/src/message.cpp
+++ b/proton-c/bindings/cpp/src/message.cpp
@@ -44,6 +44,8 @@ message::message(const message &m) : message_(::pn_message()) { *this = m; }
 message::message(message &&m) : message_(::pn_message()) { swap(m); }
 #endif
 
+message::message(const value& v) : message_(::pn_message()) { body(v); }
+
 message::~message() { ::pn_message_free(message_); }
 
 void message::swap(message& m) { std::swap(message_, m.message_); }
@@ -161,6 +163,10 @@ std::string message::reply_to_group_id() const {
     return s ? std::string(s) : std::string();
 }
 
+bool message::inferred() const { return pn_message_is_inferred(message_); }
+
+void message::inferred(bool b) { pn_message_set_inferred(message_, b); }
+
 void message::body(const value& v) { body() = v; }
 
 const data& message::body() const {
@@ -171,6 +177,58 @@ data& message::body() {
     return *data::cast(pn_message_body(message_));
 }
 
+void message::properties(const value& v) {
+    properties() = v;
+}
+
+const data& message::properties() const {
+    return *data::cast(pn_message_properties(message_));
+}
+
+data& message::properties() {
+    return *data::cast(pn_message_properties(message_));
+}
+
+namespace {
+typedef std::map<std::string, value> props_map;
+}
+
+void message::property(const std::string& name, const value &v) {
+    // TODO aconway 2015-11-17: not efficient but avoids cache consistency problems.
+    // Could avoid full encode/decode with linear scan of names. Need
+    // better codec suport for in-place modification of data.
+    props_map m;
+    if (!properties().empty())
+        properties().get(m);
+    m[name] = v;
+    properties(m);
+}
+
+value message::property(const std::string& name) const {
+    // TODO aconway 2015-11-17: not efficient but avoids cache consistency problems.
+    if (!properties().empty()) {
+        props_map m;
+        properties().get(m);
+        props_map::const_iterator i = m.find(name);
+        if (i != m.end())
+            return i->second;
+    }
+    return value();
+}
+
+bool message::erase_property(const std::string& name) {
+    // TODO aconway 2015-11-17: not efficient but avoids cache consistency problems.
+    if (!properties().empty()) {
+        props_map m;
+        properties().get(m);
+        if (m.erase(name)) {
+            properties(m);
+            return true;
+        }
+    }
+    return false;
+}
+
 void message::encode(std::string &s) const {
     size_t sz = s.capacity();
     if (sz < 512) sz = 512;

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/89923cf5/proton-c/bindings/cpp/src/message_test.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/message_test.cpp b/proton-c/bindings/cpp/src/message_test.cpp
new file mode 100644
index 0000000..928e5a6
--- /dev/null
+++ b/proton-c/bindings/cpp/src/message_test.cpp
@@ -0,0 +1,89 @@
+/*
+ * 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 "proton/message.hpp"
+#include "test_bits.hpp"
+#include <string>
+#include <fstream>
+#include <streambuf>
+#include <iosfwd>
+
+using namespace std;
+using namespace proton;
+
+
+#define CHECK_STR(ATTR) \
+    m.ATTR(#ATTR); \
+    ASSERT_EQUAL(std::string(#ATTR), m.ATTR())
+
+#define CHECK_STR_VALUE(ATTR) \
+    m.ATTR(#ATTR); \
+    ASSERT_EQUAL(std::string(#ATTR), m.ATTR().get<std::string>())
+
+void test_message() {
+    message m("hello");
+    std::string s = m.body().get<std::string>();
+    ASSERT_EQUAL("hello", s);
+
+    CHECK_STR_VALUE(id);
+    CHECK_STR(user_id);
+    CHECK_STR(address);
+    CHECK_STR(subject);
+    CHECK_STR(reply_to);
+    CHECK_STR_VALUE(correlation_id);
+    CHECK_STR(content_type);
+    CHECK_STR(content_encoding);
+    CHECK_STR(group_id);
+    CHECK_STR(reply_to_group_id);
+
+    m.expiry_time(42);
+    ASSERT_EQUAL(m.expiry_time().milliseconds, 42);
+    m.creation_time(4242);
+    ASSERT_EQUAL(m.creation_time().milliseconds, 4242);
+
+    m.property("foo", 12);
+    ASSERT_EQUAL(m.property("foo"), value(12));
+    m.property("xxx", false);
+    ASSERT_EQUAL(m.property("xxx"), value(false));
+    ASSERT(m.erase_property("xxx"));
+    ASSERT(m.property("xxx").empty());
+    ASSERT(!m.erase_property("yyy"));
+
+    std::map<std::string, proton::value> props;
+    m.properties().get(props);
+    ASSERT_EQUAL(props.size(), 1);
+    ASSERT_EQUAL(props["foo"], value(12));
+    props["bar"] = amqp_symbol("xyz");
+    props["foo"] = true;
+    m.properties(props);
+    ASSERT_EQUAL(m.property("foo"), value(true));
+    ASSERT_EQUAL(m.property("bar"), value(amqp_symbol("xyz")));
+    m.property("bar", amqp_binary("bar"));
+    std::map<std::string, proton::value> props2;
+    m.properties().get(props2);
+    ASSERT_EQUAL(2, props2.size());
+    ASSERT_EQUAL(props2["foo"], value(true));
+    ASSERT_EQUAL(props2["bar"], value(amqp_binary("bar")));
+}
+
+int main(int argc, char** argv) {
+    int failed = 0;
+    failed += RUN_TEST(test_message);
+    return failed;
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org