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/12/29 22:00:52 UTC
[1/4] qpid-proton git commit: PROTON-1085: c++: Rename "atom" type to
"scalar".
Repository: qpid-proton
Updated Branches:
refs/heads/master fd52a332f -> 117bb7cb0
PROTON-1085: c++: Rename "atom" type to "scalar".
Scalar is the term used in the AMQP standard.
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/d2c5a5f2
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/d2c5a5f2
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/d2c5a5f2
Branch: refs/heads/master
Commit: d2c5a5f2017ed95102b03b173ad050e616fab30b
Parents: fd52a33
Author: Alan Conway <ac...@redhat.com>
Authored: Mon Dec 28 15:37:23 2015 -0500
Committer: Alan Conway <ac...@redhat.com>
Committed: Tue Dec 29 15:55:38 2015 -0500
----------------------------------------------------------------------
proton-c/bindings/cpp/CMakeLists.txt | 4 +-
proton-c/bindings/cpp/include/proton/atom.hpp | 122 ------------
proton-c/bindings/cpp/include/proton/scalar.hpp | 122 ++++++++++++
proton-c/bindings/cpp/include/proton/types.hpp | 14 +-
proton-c/bindings/cpp/src/atom.cpp | 185 -------------------
proton-c/bindings/cpp/src/atom_test.cpp | 105 -----------
proton-c/bindings/cpp/src/scalar.cpp | 185 +++++++++++++++++++
proton-c/bindings/cpp/src/scalar_test.cpp | 105 +++++++++++
proton-c/bindings/cpp/src/types.cpp | 18 +-
9 files changed, 430 insertions(+), 430 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d2c5a5f2/proton-c/bindings/cpp/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/CMakeLists.txt b/proton-c/bindings/cpp/CMakeLists.txt
index 78df0b5..10d40f8 100644
--- a/proton-c/bindings/cpp/CMakeLists.txt
+++ b/proton-c/bindings/cpp/CMakeLists.txt
@@ -26,7 +26,7 @@ include_directories(
set(qpid-proton-cpp-source
src/acceptor.cpp
- src/atom.cpp
+ src/scalar.cpp
src/blocking_connection.cpp
src/blocking_connection_impl.cpp
src/blocking_fetcher.cpp
@@ -170,4 +170,4 @@ endmacro(add_cpp_test)
add_cpp_test(interop_test ${CMAKE_SOURCE_DIR}/tests)
add_cpp_test(message_test)
add_cpp_test(encode_decode_test)
-add_cpp_test(atom_test)
+add_cpp_test(scalar_test)
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d2c5a5f2/proton-c/bindings/cpp/include/proton/atom.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/atom.hpp b/proton-c/bindings/cpp/include/proton/atom.hpp
deleted file mode 100644
index ce2a385..0000000
--- a/proton-c/bindings/cpp/include/proton/atom.hpp
+++ /dev/null
@@ -1,122 +0,0 @@
-#ifndef ATOM_HPP
-#define ATOM_HPP
-/*
- * 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/types.hpp"
-#include <iosfwd>
-
-namespace proton {
-
-class atom;
-
-/** atom holds an instance of an atomic proton type. */
-class atom : public comparable<atom> {
- public:
- PN_CPP_EXTERN atom();
- // Use default assign and copy.
-
- /// Type for the value in the atom, NULL_TYPE if empty()
- PN_CPP_EXTERN type_id type() const;
- /// True if the atom is empty.
- PN_CPP_EXTERN bool empty() const;
-
- ///@name Create an atom, type() is deduced from the C++ type of the value.
- ///@{
- PN_CPP_EXTERN explicit atom(bool);
- PN_CPP_EXTERN explicit atom(uint8_t);
- PN_CPP_EXTERN explicit atom(int8_t);
- PN_CPP_EXTERN explicit atom(uint16_t);
- PN_CPP_EXTERN explicit atom(int16_t);
- PN_CPP_EXTERN explicit atom(uint32_t);
- PN_CPP_EXTERN explicit atom(int32_t);
- PN_CPP_EXTERN explicit atom(uint64_t);
- PN_CPP_EXTERN explicit atom(int64_t);
- PN_CPP_EXTERN explicit atom(wchar_t);
- PN_CPP_EXTERN explicit atom(float);
- PN_CPP_EXTERN explicit atom(double);
- PN_CPP_EXTERN explicit atom(amqp_timestamp);
- PN_CPP_EXTERN explicit atom(const amqp_decimal32&);
- PN_CPP_EXTERN explicit atom(const amqp_decimal64&);
- PN_CPP_EXTERN explicit atom(const amqp_decimal128&);
- PN_CPP_EXTERN explicit atom(const amqp_uuid&);
- PN_CPP_EXTERN explicit atom(const amqp_string&);
- PN_CPP_EXTERN explicit atom(const amqp_symbol&);
- PN_CPP_EXTERN explicit atom(const amqp_binary&);
- PN_CPP_EXTERN explicit atom(const std::string& s); ///< Treated as an AMQP string
- PN_CPP_EXTERN explicit atom(const char* s); ///< Treated as an AMQP string
- ///@}
-
- /// Assign to an atom using the same rules as construction.
- template <class T> atom& operator=(T x) { return *this = atom(x); }
-
- ///@name get(T&) extracts the value if the types match exactly,
- ///i.e. if `type() == type_id_of<T>::value`
- /// throws type_mismatch otherwise.
- ///@{
- PN_CPP_EXTERN void get(bool&) const;
- PN_CPP_EXTERN void get(uint8_t&) const;
- PN_CPP_EXTERN void get(int8_t&) const;
- PN_CPP_EXTERN void get(uint16_t&) const;
- PN_CPP_EXTERN void get(int16_t&) const;
- PN_CPP_EXTERN void get(uint32_t&) const;
- PN_CPP_EXTERN void get(int32_t&) const;
- PN_CPP_EXTERN void get(uint64_t&) const;
- PN_CPP_EXTERN void get(int64_t&) const;
- PN_CPP_EXTERN void get(wchar_t&) const;
- PN_CPP_EXTERN void get(float&) const;
- PN_CPP_EXTERN void get(double&) const;
- PN_CPP_EXTERN void get(amqp_timestamp&) const;
- PN_CPP_EXTERN void get(amqp_decimal32&) const;
- PN_CPP_EXTERN void get(amqp_decimal64&) const;
- PN_CPP_EXTERN void get(amqp_decimal128&) const;
- PN_CPP_EXTERN void get(amqp_uuid&) const;
- PN_CPP_EXTERN void get(amqp_string&) const;
- PN_CPP_EXTERN void get(amqp_symbol&) const;
- PN_CPP_EXTERN void get(amqp_binary&) const;
- PN_CPP_EXTERN void get(std::string&) const; ///< Treated as an AMQP string
- ///@}
-
- ///@ get<T>() is like get(T&) but returns the value..
- template<class T> T get() const { T x; get(x); return x; }
-
- ///@name as_ methods do "loose" conversion, they will convert the atom's
- ///value to the requested type if possible, else throw type_mismatch
- ///@{
- PN_CPP_EXTERN int64_t as_int() const; ///< Allowed if type_id_integral(type())
- PN_CPP_EXTERN uint64_t as_uint() const; ///< Allowed if type_id_integral(type())
- PN_CPP_EXTERN double as_double() const; ///< Allowed if type_id_floating_point(type())
- PN_CPP_EXTERN std::string as_string() const; ///< Allowed if type_id_string_like(type())
- ///@}
-
- PN_CPP_EXTERN bool operator==(const atom& x) const;
- /// Note if the values are of different type(), operator< will compare the type()
- PN_CPP_EXTERN bool operator<(const atom& x) const;
-
- PN_CPP_EXTERN friend std::ostream& operator<<(std::ostream&, const atom&);
-
- private:
- void ok(pn_type_t) const;
- void set(const std::string&);
- pn_atom_t atom_;
- std::string str_; // Owner of string-like data.
-};
-
-}
-#endif // ATOM_HPP
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d2c5a5f2/proton-c/bindings/cpp/include/proton/scalar.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/scalar.hpp b/proton-c/bindings/cpp/include/proton/scalar.hpp
new file mode 100644
index 0000000..0745281
--- /dev/null
+++ b/proton-c/bindings/cpp/include/proton/scalar.hpp
@@ -0,0 +1,122 @@
+#ifndef SCALAR_HPP
+#define SCALAR_HPP
+/*
+ * 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/types.hpp"
+#include <iosfwd>
+
+namespace proton {
+
+class scalar;
+
+/** scalar holds an instance of an atomic proton type. */
+class scalar : public comparable<scalar> {
+ public:
+ PN_CPP_EXTERN scalar();
+ // Use default assign and copy.
+
+ /// Type for the value in the scalar, NULL_TYPE if empty()
+ PN_CPP_EXTERN type_id type() const;
+ /// True if the scalar is empty.
+ PN_CPP_EXTERN bool empty() const;
+
+ ///@name Create an scalar, type() is deduced from the C++ type of the value.
+ ///@{
+ PN_CPP_EXTERN explicit scalar(bool);
+ PN_CPP_EXTERN explicit scalar(uint8_t);
+ PN_CPP_EXTERN explicit scalar(int8_t);
+ PN_CPP_EXTERN explicit scalar(uint16_t);
+ PN_CPP_EXTERN explicit scalar(int16_t);
+ PN_CPP_EXTERN explicit scalar(uint32_t);
+ PN_CPP_EXTERN explicit scalar(int32_t);
+ PN_CPP_EXTERN explicit scalar(uint64_t);
+ PN_CPP_EXTERN explicit scalar(int64_t);
+ PN_CPP_EXTERN explicit scalar(wchar_t);
+ PN_CPP_EXTERN explicit scalar(float);
+ PN_CPP_EXTERN explicit scalar(double);
+ PN_CPP_EXTERN explicit scalar(amqp_timestamp);
+ PN_CPP_EXTERN explicit scalar(const amqp_decimal32&);
+ PN_CPP_EXTERN explicit scalar(const amqp_decimal64&);
+ PN_CPP_EXTERN explicit scalar(const amqp_decimal128&);
+ PN_CPP_EXTERN explicit scalar(const amqp_uuid&);
+ PN_CPP_EXTERN explicit scalar(const amqp_string&);
+ PN_CPP_EXTERN explicit scalar(const amqp_symbol&);
+ PN_CPP_EXTERN explicit scalar(const amqp_binary&);
+ PN_CPP_EXTERN explicit scalar(const std::string& s); ///< Treated as an AMQP string
+ PN_CPP_EXTERN explicit scalar(const char* s); ///< Treated as an AMQP string
+ ///@}
+
+ /// Assign to an scalar using the same rules as construction.
+ template <class T> scalar& operator=(T x) { return *this = scalar(x); }
+
+ ///@name get(T&) extracts the value if the types match exactly,
+ ///i.e. if `type() == type_id_of<T>::value`
+ /// throws type_mismatch otherwise.
+ ///@{
+ PN_CPP_EXTERN void get(bool&) const;
+ PN_CPP_EXTERN void get(uint8_t&) const;
+ PN_CPP_EXTERN void get(int8_t&) const;
+ PN_CPP_EXTERN void get(uint16_t&) const;
+ PN_CPP_EXTERN void get(int16_t&) const;
+ PN_CPP_EXTERN void get(uint32_t&) const;
+ PN_CPP_EXTERN void get(int32_t&) const;
+ PN_CPP_EXTERN void get(uint64_t&) const;
+ PN_CPP_EXTERN void get(int64_t&) const;
+ PN_CPP_EXTERN void get(wchar_t&) const;
+ PN_CPP_EXTERN void get(float&) const;
+ PN_CPP_EXTERN void get(double&) const;
+ PN_CPP_EXTERN void get(amqp_timestamp&) const;
+ PN_CPP_EXTERN void get(amqp_decimal32&) const;
+ PN_CPP_EXTERN void get(amqp_decimal64&) const;
+ PN_CPP_EXTERN void get(amqp_decimal128&) const;
+ PN_CPP_EXTERN void get(amqp_uuid&) const;
+ PN_CPP_EXTERN void get(amqp_string&) const;
+ PN_CPP_EXTERN void get(amqp_symbol&) const;
+ PN_CPP_EXTERN void get(amqp_binary&) const;
+ PN_CPP_EXTERN void get(std::string&) const; ///< Treated as an AMQP string
+ ///@}
+
+ ///@ get<T>() is like get(T&) but returns the value..
+ template<class T> T get() const { T x; get(x); return x; }
+
+ ///@name as_ methods do "loose" conversion, they will convert the scalar's
+ ///value to the requested type if possible, else throw type_mismatch
+ ///@{
+ PN_CPP_EXTERN int64_t as_int() const; ///< Allowed if type_id_integral(type())
+ PN_CPP_EXTERN uint64_t as_uint() const; ///< Allowed if type_id_integral(type())
+ PN_CPP_EXTERN double as_double() const; ///< Allowed if type_id_floating_point(type())
+ PN_CPP_EXTERN std::string as_string() const; ///< Allowed if type_id_string_like(type())
+ ///@}
+
+ PN_CPP_EXTERN bool operator==(const scalar& x) const;
+ /// Note if the values are of different type(), operator< will compare the type()
+ PN_CPP_EXTERN bool operator<(const scalar& x) const;
+
+ PN_CPP_EXTERN friend std::ostream& operator<<(std::ostream&, const scalar&);
+
+ private:
+ void ok(pn_type_t) const;
+ void set(const std::string&);
+ pn_atom_t atom_;
+ std::string str_; // Owner of string-like data.
+};
+
+}
+#endif // SCALAR_HPP
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d2c5a5f2/proton-c/bindings/cpp/include/proton/types.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/types.hpp b/proton-c/bindings/cpp/include/proton/types.hpp
index 75bb226..645d9da 100644
--- a/proton-c/bindings/cpp/include/proton/types.hpp
+++ b/proton-c/bindings/cpp/include/proton/types.hpp
@@ -198,13 +198,13 @@ PN_CPP_EXTERN std::string type_name(type_id);
///@name Attributes of a type_id value, returns same result as the
/// corresponding std::type_traits tests for the corresponding C++ types.
///@{
-PN_CPP_EXTERN bool type_id_atom(type_id);
-PN_CPP_EXTERN bool type_id_integral(type_id);
-PN_CPP_EXTERN bool type_id_signed(type_id); ///< CHAR and BOOL are not signed.
-PN_CPP_EXTERN bool type_id_floating_point(type_id);
-PN_CPP_EXTERN bool type_id_decimal(type_id);
-PN_CPP_EXTERN bool type_id_string_like(type_id); ///< STRING, SYMBOL, BINARY
-PN_CPP_EXTERN bool type_id_container(type_id);
+PN_CPP_EXTERN bool type_id_is_scalar(type_id);
+PN_CPP_EXTERN bool type_id_is_integral(type_id);
+PN_CPP_EXTERN bool type_id_is_signed(type_id); ///< CHAR and BOOL are not signed.
+PN_CPP_EXTERN bool type_id_is_floating_point(type_id);
+PN_CPP_EXTERN bool type_id_is_decimal(type_id);
+PN_CPP_EXTERN bool type_id_is_string_like(type_id); ///< STRING, SYMBOL, BINARY
+PN_CPP_EXTERN bool type_id_is_container(type_id);
///@}
/** Print the name of a type. */
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d2c5a5f2/proton-c/bindings/cpp/src/atom.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/atom.cpp b/proton-c/bindings/cpp/src/atom.cpp
deleted file mode 100644
index 034b22c..0000000
--- a/proton-c/bindings/cpp/src/atom.cpp
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-#include "proton/atom.hpp"
-#include "proton/type_traits.hpp"
-
-#include <ostream>
-
-namespace proton {
-
-atom::atom() { atom_.type = PN_NULL; }
-
-type_id atom::type() const { return type_id(atom_.type); }
-bool atom::empty() const { return type() == NULL_TYPE; }
-
-atom::atom(bool x) { atom_.u.as_bool = x; atom_.type = PN_BOOL; }
-atom::atom(uint8_t x) { atom_.u.as_ubyte = x; atom_.type = PN_UBYTE; }
-atom::atom(int8_t x) { atom_.u.as_byte = x; atom_.type = PN_BYTE; }
-atom::atom(uint16_t x) { atom_.u.as_ushort = x; atom_.type = PN_USHORT; }
-atom::atom(int16_t x) { atom_.u.as_short = x; atom_.type = PN_SHORT; }
-atom::atom(uint32_t x) { atom_.u.as_uint = x; atom_.type = PN_UINT; }
-atom::atom(int32_t x) { atom_.u.as_int = x; atom_.type = PN_INT; }
-atom::atom(uint64_t x) { atom_.u.as_ulong = x; atom_.type = PN_ULONG; }
-atom::atom(int64_t x) { atom_.u.as_long = x; atom_.type = PN_LONG; }
-atom::atom(wchar_t x) { atom_.u.as_char = pn_char_t(x); atom_.type = PN_CHAR; }
-atom::atom(float x) { atom_.u.as_float = x; atom_.type = PN_FLOAT; }
-atom::atom(double x) { atom_.u.as_double = x; atom_.type = PN_DOUBLE; }
-atom::atom(amqp_timestamp x) { atom_.u.as_timestamp = x; atom_.type = PN_TIMESTAMP; }
-atom::atom(const amqp_decimal32& x) { atom_.u.as_decimal32 = x; atom_.type = PN_DECIMAL32; }
-atom::atom(const amqp_decimal64& x) { atom_.u.as_decimal64 = x; atom_.type = PN_DECIMAL64; }
-atom::atom(const amqp_decimal128& x) { atom_.u.as_decimal128 = x; atom_.type = PN_DECIMAL128; }
-atom::atom(const amqp_uuid& x) { atom_.u.as_uuid = x; atom_.type = PN_UUID; }
-
-void atom::set(const std::string& x) { str_ = x; atom_.u.as_bytes = pn_bytes(str_); }
-atom::atom(const amqp_string& x) { set(x); atom_.type = PN_STRING; }
-atom::atom(const amqp_symbol& x) { set(x); atom_.type = PN_SYMBOL; }
-atom::atom(const amqp_binary& x) { set(x); atom_.type = PN_BINARY; }
-atom::atom(const std::string& x) { *this = amqp_string(x); }
-atom::atom(const char* x) { *this = amqp_string(x); }
-
-void atom::ok(pn_type_t t) const {
- if (atom_.type != t) throw type_mismatch(type_id(t), type());
-}
-
-void atom::get(bool& x) const { ok(PN_BOOL); x = atom_.u.as_bool; }
-void atom::get(uint8_t& x) const { ok(PN_UBYTE); x = atom_.u.as_ubyte; }
-void atom::get(int8_t& x) const { ok(PN_BYTE); x = atom_.u.as_byte; }
-void atom::get(uint16_t& x) const { ok(PN_USHORT); x = atom_.u.as_ushort; }
-void atom::get(int16_t& x) const { ok(PN_SHORT); x = atom_.u.as_short; }
-void atom::get(uint32_t& x) const { ok(PN_UINT); x = atom_.u.as_uint; }
-void atom::get(int32_t& x) const { ok(PN_INT); x = atom_.u.as_int; }
-void atom::get(wchar_t& x) const { ok(PN_CHAR); x = wchar_t(atom_.u.as_char); }
-void atom::get(uint64_t& x) const { ok(PN_ULONG); x = atom_.u.as_ulong; }
-void atom::get(int64_t& x) const { ok(PN_LONG); x = atom_.u.as_long; }
-void atom::get(amqp_timestamp& x) const { ok(PN_TIMESTAMP); x = atom_.u.as_timestamp; }
-void atom::get(float& x) const { ok(PN_FLOAT); x = atom_.u.as_float; }
-void atom::get(double& x) const { ok(PN_DOUBLE); x = atom_.u.as_double; }
-void atom::get(amqp_decimal32& x) const { ok(PN_DECIMAL32); x = atom_.u.as_decimal32; }
-void atom::get(amqp_decimal64& x) const { ok(PN_DECIMAL64); x = atom_.u.as_decimal64; }
-void atom::get(amqp_decimal128& x) const { ok(PN_DECIMAL128); x = atom_.u.as_decimal128; }
-void atom::get(amqp_uuid& x) const { ok(PN_UUID); x = atom_.u.as_uuid; }
-void atom::get(amqp_string& x) const { ok(PN_STRING); x = str_; }
-void atom::get(amqp_symbol& x) const { ok(PN_SYMBOL); x = str_; }
-void atom::get(amqp_binary& x) const { ok(PN_BINARY); x = str_; }
-void atom::get(std::string& x) const { x = get<amqp_string>(); }
-
-int64_t atom::as_int() const {
- if (type_id_floating_point(type()))
- return int64_t(as_double());
- switch (atom_.type) {
- case PN_BOOL: return atom_.u.as_bool;
- case PN_UBYTE: return atom_.u.as_ubyte;
- case PN_BYTE: return atom_.u.as_byte;
- case PN_USHORT: return atom_.u.as_ushort;
- case PN_SHORT: return atom_.u.as_short;
- case PN_UINT: return atom_.u.as_uint;
- case PN_INT: return atom_.u.as_int;
- case PN_CHAR: return atom_.u.as_char;
- case PN_ULONG: return int64_t(atom_.u.as_ulong);
- case PN_LONG: return atom_.u.as_long;
- default: throw type_mismatch(LONG, type(), "cannot convert");
- }
-}
-
-uint64_t atom::as_uint() const {
- if (!type_id_integral(type()))
- throw type_mismatch(ULONG, type(), "cannot convert");
- return uint64_t(as_int());
-}
-
-double atom::as_double() const {
- if (type_id_integral(type())) {
- return type_id_signed(type()) ? double(as_int()) : double(as_uint());
- }
- switch (atom_.type) {
- case PN_DOUBLE: return atom_.u.as_double;
- case PN_FLOAT: return atom_.u.as_float;
- default: throw type_mismatch(DOUBLE, type(), "cannot convert");
- }
-}
-
-std::string atom::as_string() const {
- if (type_id_string_like(type()))
- return str_;
- throw type_mismatch(DOUBLE, type(), "cannot convert");
-}
-
-
-namespace {
-template <class T, class F> T type_switch(const atom& a, F f) {
- switch(a.type()) {
- case BOOLEAN: return f(a.get<bool>());
- case UBYTE: return f(a.get<uint8_t>());
- case BYTE: return f(a.get<int8_t>());
- case USHORT: return f(a.get<uint16_t>());
- case SHORT: return f(a.get<int16_t>());
- case UINT: return f(a.get<uint32_t>());
- case INT: return f(a.get<int32_t>());
- case CHAR: return f(a.get<wchar_t>());
- case ULONG: return f(a.get<uint64_t>());
- case LONG: return f(a.get<int64_t>());
- case TIMESTAMP: return f(a.get<amqp_timestamp>());
- case FLOAT: return f(a.get<float>());
- case DOUBLE: return f(a.get<double>());
- case DECIMAL32: return f(a.get<amqp_decimal32>());
- case DECIMAL64: return f(a.get<amqp_decimal64>());
- case DECIMAL128: return f(a.get<amqp_decimal128>());
- case UUID: return f(a.get<amqp_uuid>());
- case BINARY: return f(a.get<amqp_binary>());
- case STRING: return f(a.get<amqp_string>());
- case SYMBOL: return f(a.get<amqp_symbol>());
- default:
- throw error("bad atom type");
- }
-}
-
-struct equal_op {
- const atom& a;
- equal_op(const atom& a_) : a(a_) {}
- template<class T> bool operator()(T x) { return x == a.get<T>(); }
-};
-
-struct less_op {
- const atom& a;
- less_op(const atom& a_) : a(a_) {}
- template<class T> bool operator()(T x) { return x < a.get<T>(); }
-};
-
-struct ostream_op {
- std::ostream& o;
- ostream_op(std::ostream& o_) : o(o_) {}
- template<class T> std::ostream& operator()(T x) { return o << x; }
-};
-
-} // namespace
-
-bool atom::operator==(const atom& x) const {
- return type_switch<bool>(*this, equal_op(x));
-}
-
-bool atom::operator<(const atom& x) const {
- return type_switch<bool>(*this, less_op(x));
-}
-
-std::ostream& operator<<(std::ostream& o, const atom& a) {
- return type_switch<std::ostream&>(a, ostream_op(o));
-}
-
-}
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d2c5a5f2/proton-c/bindings/cpp/src/atom_test.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/atom_test.cpp b/proton-c/bindings/cpp/src/atom_test.cpp
deleted file mode 100644
index 0d85a36..0000000
--- a/proton-c/bindings/cpp/src/atom_test.cpp
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-#include "test_bits.hpp"
-#include "proton/type_traits.hpp"
-
-#include <proton/atom.hpp>
-
-using namespace std;
-using namespace proton;
-
-// Inserting and extracting simple C++ values.
-template <class T> void type_test(T x, type_id tid, T y) {
- atom v(x);
- ASSERT_EQUAL(tid, v.type());
- ASSERT(!v.empty());
- ASSERT_EQUAL(x, v.get<T>());
-
- atom v2;
- ASSERT(v2.type() == NULL_TYPE);
- v2 = x;
- ASSERT_EQUAL(tid, v2.type());
- ASSERT_EQUAL(x, v2.get<T>());
- ASSERT_EQUAL(v, v2);
- ASSERT_EQUAL(str(x), str(v));
-
- v2 = y;
- ASSERT(v != v2);
- ASSERT(v < v2);
- ASSERT(v2 > v);
-}
-
-#define ASSERT_MISMATCH(EXPR) \
- try { (void)(EXPR); FAIL("expected type_mismatch: " #EXPR); } catch (type_mismatch) {}
-
-void convert_test() {
- atom a;
- ASSERT_EQUAL(NULL_TYPE, a.type());
- ASSERT(a.empty());
- ASSERT_MISMATCH(a.get<float>());
-
- a = amqp_binary("foo");
- ASSERT_MISMATCH(a.get<int16_t>());
- ASSERT_MISMATCH(a.as_int());
- ASSERT_MISMATCH(a.as_double());
- ASSERT_MISMATCH(a.get<amqp_string>()); // No strict conversion
- ASSERT_EQUAL(a.as_string(), std::string("foo")); // OK string-like conversion
-
- a = int16_t(42);
- ASSERT_MISMATCH(a.get<std::string>());
- ASSERT_MISMATCH(a.get<amqp_timestamp>());
- ASSERT_MISMATCH(a.as_string());
- ASSERT_EQUAL(a.as_int(), 42);
- ASSERT_EQUAL(a.as_uint(), 42);
- ASSERT_EQUAL(a.as_double(), 42);
-
- a = int16_t(-42);
- ASSERT_EQUAL(a.as_int(), -42);
- ASSERT_EQUAL(a.as_uint(), uint64_t(-42));
- ASSERT_EQUAL(a.as_double(), -42);
-}
-
-int main(int, char**) {
- int failed = 0;
- RUN_TEST(failed, type_test(false, BOOLEAN, true));
- RUN_TEST(failed, type_test(amqp_ubyte(42), UBYTE, amqp_ubyte(50)));
- RUN_TEST(failed, type_test(amqp_byte('x'), BYTE, amqp_byte('y')));
- RUN_TEST(failed, type_test(amqp_ushort(4242), USHORT, amqp_ushort(5252)));
- RUN_TEST(failed, type_test(amqp_short(-4242), SHORT, amqp_short(3)));
- RUN_TEST(failed, type_test(amqp_uint(4242), UINT, amqp_uint(5252)));
- RUN_TEST(failed, type_test(amqp_int(-4242), INT, amqp_int(3)));
- RUN_TEST(failed, type_test(amqp_ulong(4242), ULONG, amqp_ulong(5252)));
- RUN_TEST(failed, type_test(amqp_long(-4242), LONG, amqp_long(3)));
- RUN_TEST(failed, type_test(wchar_t(23), CHAR, wchar_t(24)));
- RUN_TEST(failed, type_test(amqp_float(1.234), FLOAT, amqp_float(2.345)));
- RUN_TEST(failed, type_test(amqp_double(11.2233), DOUBLE, amqp_double(12)));
- RUN_TEST(failed, type_test(amqp_timestamp(0), TIMESTAMP, amqp_timestamp(1)));
- RUN_TEST(failed, type_test(amqp_decimal32(0), DECIMAL32, amqp_decimal32(1)));
- RUN_TEST(failed, type_test(amqp_decimal64(0), DECIMAL64, amqp_decimal64(1)));
- pn_decimal128_t da = {0}, db = {1};
- RUN_TEST(failed, type_test(amqp_decimal128(da), DECIMAL128, amqp_decimal128(db)));
- pn_uuid_t ua = {0}, ub = {1};
- RUN_TEST(failed, type_test(amqp_uuid(ua), UUID, amqp_uuid(ub)));
- RUN_TEST(failed, type_test(amqp_string("aaa"), STRING, amqp_string("aaaa")));
- RUN_TEST(failed, type_test(amqp_symbol("aaa"), SYMBOL, amqp_symbol("aaaa")));
- RUN_TEST(failed, type_test(amqp_binary("aaa"), BINARY, amqp_binary("aaaa")));
- RUN_TEST(failed, type_test(std::string("xxx"), STRING, std::string("yyy")));
- return failed;
-}
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d2c5a5f2/proton-c/bindings/cpp/src/scalar.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/scalar.cpp b/proton-c/bindings/cpp/src/scalar.cpp
new file mode 100644
index 0000000..13daf32
--- /dev/null
+++ b/proton-c/bindings/cpp/src/scalar.cpp
@@ -0,0 +1,185 @@
+/*
+ * 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/scalar.hpp"
+#include "proton/type_traits.hpp"
+
+#include <ostream>
+
+namespace proton {
+
+scalar::scalar() { atom_.type = PN_NULL; }
+
+type_id scalar::type() const { return type_id(atom_.type); }
+bool scalar::empty() const { return type() == NULL_TYPE; }
+
+scalar::scalar(bool x) { atom_.u.as_bool = x; atom_.type = PN_BOOL; }
+scalar::scalar(uint8_t x) { atom_.u.as_ubyte = x; atom_.type = PN_UBYTE; }
+scalar::scalar(int8_t x) { atom_.u.as_byte = x; atom_.type = PN_BYTE; }
+scalar::scalar(uint16_t x) { atom_.u.as_ushort = x; atom_.type = PN_USHORT; }
+scalar::scalar(int16_t x) { atom_.u.as_short = x; atom_.type = PN_SHORT; }
+scalar::scalar(uint32_t x) { atom_.u.as_uint = x; atom_.type = PN_UINT; }
+scalar::scalar(int32_t x) { atom_.u.as_int = x; atom_.type = PN_INT; }
+scalar::scalar(uint64_t x) { atom_.u.as_ulong = x; atom_.type = PN_ULONG; }
+scalar::scalar(int64_t x) { atom_.u.as_long = x; atom_.type = PN_LONG; }
+scalar::scalar(wchar_t x) { atom_.u.as_char = pn_char_t(x); atom_.type = PN_CHAR; }
+scalar::scalar(float x) { atom_.u.as_float = x; atom_.type = PN_FLOAT; }
+scalar::scalar(double x) { atom_.u.as_double = x; atom_.type = PN_DOUBLE; }
+scalar::scalar(amqp_timestamp x) { atom_.u.as_timestamp = x; atom_.type = PN_TIMESTAMP; }
+scalar::scalar(const amqp_decimal32& x) { atom_.u.as_decimal32 = x; atom_.type = PN_DECIMAL32; }
+scalar::scalar(const amqp_decimal64& x) { atom_.u.as_decimal64 = x; atom_.type = PN_DECIMAL64; }
+scalar::scalar(const amqp_decimal128& x) { atom_.u.as_decimal128 = x; atom_.type = PN_DECIMAL128; }
+scalar::scalar(const amqp_uuid& x) { atom_.u.as_uuid = x; atom_.type = PN_UUID; }
+
+void scalar::set(const std::string& x) { str_ = x; atom_.u.as_bytes = pn_bytes(str_); }
+scalar::scalar(const amqp_string& x) { set(x); atom_.type = PN_STRING; }
+scalar::scalar(const amqp_symbol& x) { set(x); atom_.type = PN_SYMBOL; }
+scalar::scalar(const amqp_binary& x) { set(x); atom_.type = PN_BINARY; }
+scalar::scalar(const std::string& x) { *this = amqp_string(x); }
+scalar::scalar(const char* x) { *this = amqp_string(x); }
+
+void scalar::ok(pn_type_t t) const {
+ if (atom_.type != t) throw type_mismatch(type_id(t), type());
+}
+
+void scalar::get(bool& x) const { ok(PN_BOOL); x = atom_.u.as_bool; }
+void scalar::get(uint8_t& x) const { ok(PN_UBYTE); x = atom_.u.as_ubyte; }
+void scalar::get(int8_t& x) const { ok(PN_BYTE); x = atom_.u.as_byte; }
+void scalar::get(uint16_t& x) const { ok(PN_USHORT); x = atom_.u.as_ushort; }
+void scalar::get(int16_t& x) const { ok(PN_SHORT); x = atom_.u.as_short; }
+void scalar::get(uint32_t& x) const { ok(PN_UINT); x = atom_.u.as_uint; }
+void scalar::get(int32_t& x) const { ok(PN_INT); x = atom_.u.as_int; }
+void scalar::get(wchar_t& x) const { ok(PN_CHAR); x = wchar_t(atom_.u.as_char); }
+void scalar::get(uint64_t& x) const { ok(PN_ULONG); x = atom_.u.as_ulong; }
+void scalar::get(int64_t& x) const { ok(PN_LONG); x = atom_.u.as_long; }
+void scalar::get(amqp_timestamp& x) const { ok(PN_TIMESTAMP); x = atom_.u.as_timestamp; }
+void scalar::get(float& x) const { ok(PN_FLOAT); x = atom_.u.as_float; }
+void scalar::get(double& x) const { ok(PN_DOUBLE); x = atom_.u.as_double; }
+void scalar::get(amqp_decimal32& x) const { ok(PN_DECIMAL32); x = atom_.u.as_decimal32; }
+void scalar::get(amqp_decimal64& x) const { ok(PN_DECIMAL64); x = atom_.u.as_decimal64; }
+void scalar::get(amqp_decimal128& x) const { ok(PN_DECIMAL128); x = atom_.u.as_decimal128; }
+void scalar::get(amqp_uuid& x) const { ok(PN_UUID); x = atom_.u.as_uuid; }
+void scalar::get(amqp_string& x) const { ok(PN_STRING); x = str_; }
+void scalar::get(amqp_symbol& x) const { ok(PN_SYMBOL); x = str_; }
+void scalar::get(amqp_binary& x) const { ok(PN_BINARY); x = str_; }
+void scalar::get(std::string& x) const { x = get<amqp_string>(); }
+
+int64_t scalar::as_int() const {
+ if (type_id_is_floating_point(type()))
+ return int64_t(as_double());
+ switch (atom_.type) {
+ case PN_BOOL: return atom_.u.as_bool;
+ case PN_UBYTE: return atom_.u.as_ubyte;
+ case PN_BYTE: return atom_.u.as_byte;
+ case PN_USHORT: return atom_.u.as_ushort;
+ case PN_SHORT: return atom_.u.as_short;
+ case PN_UINT: return atom_.u.as_uint;
+ case PN_INT: return atom_.u.as_int;
+ case PN_CHAR: return atom_.u.as_char;
+ case PN_ULONG: return int64_t(atom_.u.as_ulong);
+ case PN_LONG: return atom_.u.as_long;
+ default: throw type_mismatch(LONG, type(), "cannot convert");
+ }
+}
+
+uint64_t scalar::as_uint() const {
+ if (!type_id_is_integral(type()))
+ throw type_mismatch(ULONG, type(), "cannot convert");
+ return uint64_t(as_int());
+}
+
+double scalar::as_double() const {
+ if (type_id_is_integral(type())) {
+ return type_id_is_signed(type()) ? double(as_int()) : double(as_uint());
+ }
+ switch (atom_.type) {
+ case PN_DOUBLE: return atom_.u.as_double;
+ case PN_FLOAT: return atom_.u.as_float;
+ default: throw type_mismatch(DOUBLE, type(), "cannot convert");
+ }
+}
+
+std::string scalar::as_string() const {
+ if (type_id_is_string_like(type()))
+ return str_;
+ throw type_mismatch(DOUBLE, type(), "cannot convert");
+}
+
+
+namespace {
+template <class T, class F> T type_switch(const scalar& a, F f) {
+ switch(a.type()) {
+ case BOOLEAN: return f(a.get<bool>());
+ case UBYTE: return f(a.get<uint8_t>());
+ case BYTE: return f(a.get<int8_t>());
+ case USHORT: return f(a.get<uint16_t>());
+ case SHORT: return f(a.get<int16_t>());
+ case UINT: return f(a.get<uint32_t>());
+ case INT: return f(a.get<int32_t>());
+ case CHAR: return f(a.get<wchar_t>());
+ case ULONG: return f(a.get<uint64_t>());
+ case LONG: return f(a.get<int64_t>());
+ case TIMESTAMP: return f(a.get<amqp_timestamp>());
+ case FLOAT: return f(a.get<float>());
+ case DOUBLE: return f(a.get<double>());
+ case DECIMAL32: return f(a.get<amqp_decimal32>());
+ case DECIMAL64: return f(a.get<amqp_decimal64>());
+ case DECIMAL128: return f(a.get<amqp_decimal128>());
+ case UUID: return f(a.get<amqp_uuid>());
+ case BINARY: return f(a.get<amqp_binary>());
+ case STRING: return f(a.get<amqp_string>());
+ case SYMBOL: return f(a.get<amqp_symbol>());
+ default:
+ throw error("bad scalar type");
+ }
+}
+
+struct equal_op {
+ const scalar& a;
+ equal_op(const scalar& a_) : a(a_) {}
+ template<class T> bool operator()(T x) { return x == a.get<T>(); }
+};
+
+struct less_op {
+ const scalar& a;
+ less_op(const scalar& a_) : a(a_) {}
+ template<class T> bool operator()(T x) { return x < a.get<T>(); }
+};
+
+struct ostream_op {
+ std::ostream& o;
+ ostream_op(std::ostream& o_) : o(o_) {}
+ template<class T> std::ostream& operator()(T x) { return o << x; }
+};
+
+} // namespace
+
+bool scalar::operator==(const scalar& x) const {
+ return type_switch<bool>(*this, equal_op(x));
+}
+
+bool scalar::operator<(const scalar& x) const {
+ return type_switch<bool>(*this, less_op(x));
+}
+
+std::ostream& operator<<(std::ostream& o, const scalar& a) {
+ return type_switch<std::ostream&>(a, ostream_op(o));
+}
+
+}
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d2c5a5f2/proton-c/bindings/cpp/src/scalar_test.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/scalar_test.cpp b/proton-c/bindings/cpp/src/scalar_test.cpp
new file mode 100644
index 0000000..c7de785
--- /dev/null
+++ b/proton-c/bindings/cpp/src/scalar_test.cpp
@@ -0,0 +1,105 @@
+/*
+ * 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 "test_bits.hpp"
+#include "proton/type_traits.hpp"
+
+#include <proton/scalar.hpp>
+
+using namespace std;
+using namespace proton;
+
+// Inserting and extracting simple C++ values.
+template <class T> void type_test(T x, type_id tid, T y) {
+ scalar v(x);
+ ASSERT_EQUAL(tid, v.type());
+ ASSERT(!v.empty());
+ ASSERT_EQUAL(x, v.get<T>());
+
+ scalar v2;
+ ASSERT(v2.type() == NULL_TYPE);
+ v2 = x;
+ ASSERT_EQUAL(tid, v2.type());
+ ASSERT_EQUAL(x, v2.get<T>());
+ ASSERT_EQUAL(v, v2);
+ ASSERT_EQUAL(str(x), str(v));
+
+ v2 = y;
+ ASSERT(v != v2);
+ ASSERT(v < v2);
+ ASSERT(v2 > v);
+}
+
+#define ASSERT_MISMATCH(EXPR) \
+ try { (void)(EXPR); FAIL("expected type_mismatch: " #EXPR); } catch (type_mismatch) {}
+
+void convert_test() {
+ scalar a;
+ ASSERT_EQUAL(NULL_TYPE, a.type());
+ ASSERT(a.empty());
+ ASSERT_MISMATCH(a.get<float>());
+
+ a = amqp_binary("foo");
+ ASSERT_MISMATCH(a.get<int16_t>());
+ ASSERT_MISMATCH(a.as_int());
+ ASSERT_MISMATCH(a.as_double());
+ ASSERT_MISMATCH(a.get<amqp_string>()); // No strict conversion
+ ASSERT_EQUAL(a.as_string(), std::string("foo")); // OK string-like conversion
+
+ a = int16_t(42);
+ ASSERT_MISMATCH(a.get<std::string>());
+ ASSERT_MISMATCH(a.get<amqp_timestamp>());
+ ASSERT_MISMATCH(a.as_string());
+ ASSERT_EQUAL(a.as_int(), 42);
+ ASSERT_EQUAL(a.as_uint(), 42);
+ ASSERT_EQUAL(a.as_double(), 42);
+
+ a = int16_t(-42);
+ ASSERT_EQUAL(a.as_int(), -42);
+ ASSERT_EQUAL(a.as_uint(), uint64_t(-42));
+ ASSERT_EQUAL(a.as_double(), -42);
+}
+
+int main(int, char**) {
+ int failed = 0;
+ RUN_TEST(failed, type_test(false, BOOLEAN, true));
+ RUN_TEST(failed, type_test(amqp_ubyte(42), UBYTE, amqp_ubyte(50)));
+ RUN_TEST(failed, type_test(amqp_byte('x'), BYTE, amqp_byte('y')));
+ RUN_TEST(failed, type_test(amqp_ushort(4242), USHORT, amqp_ushort(5252)));
+ RUN_TEST(failed, type_test(amqp_short(-4242), SHORT, amqp_short(3)));
+ RUN_TEST(failed, type_test(amqp_uint(4242), UINT, amqp_uint(5252)));
+ RUN_TEST(failed, type_test(amqp_int(-4242), INT, amqp_int(3)));
+ RUN_TEST(failed, type_test(amqp_ulong(4242), ULONG, amqp_ulong(5252)));
+ RUN_TEST(failed, type_test(amqp_long(-4242), LONG, amqp_long(3)));
+ RUN_TEST(failed, type_test(wchar_t(23), CHAR, wchar_t(24)));
+ RUN_TEST(failed, type_test(amqp_float(1.234), FLOAT, amqp_float(2.345)));
+ RUN_TEST(failed, type_test(amqp_double(11.2233), DOUBLE, amqp_double(12)));
+ RUN_TEST(failed, type_test(amqp_timestamp(0), TIMESTAMP, amqp_timestamp(1)));
+ RUN_TEST(failed, type_test(amqp_decimal32(0), DECIMAL32, amqp_decimal32(1)));
+ RUN_TEST(failed, type_test(amqp_decimal64(0), DECIMAL64, amqp_decimal64(1)));
+ pn_decimal128_t da = {0}, db = {1};
+ RUN_TEST(failed, type_test(amqp_decimal128(da), DECIMAL128, amqp_decimal128(db)));
+ pn_uuid_t ua = {0}, ub = {1};
+ RUN_TEST(failed, type_test(amqp_uuid(ua), UUID, amqp_uuid(ub)));
+ RUN_TEST(failed, type_test(amqp_string("aaa"), STRING, amqp_string("aaaa")));
+ RUN_TEST(failed, type_test(amqp_symbol("aaa"), SYMBOL, amqp_symbol("aaaa")));
+ RUN_TEST(failed, type_test(amqp_binary("aaa"), BINARY, amqp_binary("aaaa")));
+ RUN_TEST(failed, type_test(std::string("xxx"), STRING, std::string("yyy")));
+ return failed;
+}
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d2c5a5f2/proton-c/bindings/cpp/src/types.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/types.cpp b/proton-c/bindings/cpp/src/types.cpp
index d8e40ce..fa7b0bd 100644
--- a/proton-c/bindings/cpp/src/types.cpp
+++ b/proton-c/bindings/cpp/src/types.cpp
@@ -95,15 +95,15 @@ std::string type_name(type_id t) {
return "unknown";
}
-static bool type_id_signed_int(type_id t) { return t == BYTE || t == SHORT || t == INT || t == LONG; }
-static bool type_id_unsigned_int(type_id t) { return t == UBYTE || t == USHORT || t == UINT || t == ULONG; }
-bool type_id_integral(type_id t) { return t == BOOLEAN || t == CHAR || type_id_unsigned_int(t) || type_id_signed_int(t); }
-bool type_id_floating_point(type_id t) { return t == FLOAT || t == DOUBLE; }
-bool type_id_decimal(type_id t) { return t == DECIMAL32 || t == DECIMAL64 || t == DECIMAL128; }
-bool type_id_signed(type_id t) { return type_id_signed_int(t) || type_id_floating_point(t) || type_id_decimal(t); }
-bool type_id_string_like(type_id t) { return t == BINARY || t == STRING || t == SYMBOL; }
-bool type_id_container(type_id t) { return t == LIST || t == MAP || t == ARRAY || t == DESCRIBED; }
-bool type_id_atom(type_id t) { return type_id_integral(t) || type_id_floating_point(t) || type_id_decimal(t) || type_id_string_like(t) || t == TIMESTAMP || t == UUID; }
+static bool type_id_is_signed_int(type_id t) { return t == BYTE || t == SHORT || t == INT || t == LONG; }
+static bool type_id_is_unsigned_int(type_id t) { return t == UBYTE || t == USHORT || t == UINT || t == ULONG; }
+bool type_id_is_integral(type_id t) { return t == BOOLEAN || t == CHAR || type_id_is_unsigned_int(t) || type_id_is_signed_int(t); }
+bool type_id_is_floating_point(type_id t) { return t == FLOAT || t == DOUBLE; }
+bool type_id_is_decimal(type_id t) { return t == DECIMAL32 || t == DECIMAL64 || t == DECIMAL128; }
+bool type_id_is_signed(type_id t) { return type_id_is_signed_int(t) || type_id_is_floating_point(t) || type_id_is_decimal(t); }
+bool type_id_is_string_like(type_id t) { return t == BINARY || t == STRING || t == SYMBOL; }
+bool type_id_is_container(type_id t) { return t == LIST || t == MAP || t == ARRAY || t == DESCRIBED; }
+bool type_id_is_scalar(type_id t) { return type_id_is_integral(t) || type_id_is_floating_point(t) || type_id_is_decimal(t) || type_id_is_string_like(t) || t == TIMESTAMP || t == UUID; }
std::ostream& operator<<(std::ostream& o,type_id t) { return o << type_name(t); }
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org
[2/4] qpid-proton git commit: PROTON-1085: c++: clean up access to
message properties, instructions and annotations.
Posted by ac...@apache.org.
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/1622d0e6/proton-c/bindings/cpp/src/scalar.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/scalar.cpp b/proton-c/bindings/cpp/src/scalar.cpp
index 13daf32..9e8d124 100644
--- a/proton-c/bindings/cpp/src/scalar.cpp
+++ b/proton-c/bindings/cpp/src/scalar.cpp
@@ -17,6 +17,7 @@
* under the License.
*/
+#include "msg.hpp"
#include "proton/scalar.hpp"
#include "proton/type_traits.hpp"
@@ -25,37 +26,50 @@
namespace proton {
scalar::scalar() { atom_.type = PN_NULL; }
+scalar::scalar(const scalar& x) { set(x.atom_); }
+scalar& scalar::operator=(const scalar& x) { set(x.atom_); return *this; }
type_id scalar::type() const { return type_id(atom_.type); }
bool scalar::empty() const { return type() == NULL_TYPE; }
-scalar::scalar(bool x) { atom_.u.as_bool = x; atom_.type = PN_BOOL; }
-scalar::scalar(uint8_t x) { atom_.u.as_ubyte = x; atom_.type = PN_UBYTE; }
-scalar::scalar(int8_t x) { atom_.u.as_byte = x; atom_.type = PN_BYTE; }
-scalar::scalar(uint16_t x) { atom_.u.as_ushort = x; atom_.type = PN_USHORT; }
-scalar::scalar(int16_t x) { atom_.u.as_short = x; atom_.type = PN_SHORT; }
-scalar::scalar(uint32_t x) { atom_.u.as_uint = x; atom_.type = PN_UINT; }
-scalar::scalar(int32_t x) { atom_.u.as_int = x; atom_.type = PN_INT; }
-scalar::scalar(uint64_t x) { atom_.u.as_ulong = x; atom_.type = PN_ULONG; }
-scalar::scalar(int64_t x) { atom_.u.as_long = x; atom_.type = PN_LONG; }
-scalar::scalar(wchar_t x) { atom_.u.as_char = pn_char_t(x); atom_.type = PN_CHAR; }
-scalar::scalar(float x) { atom_.u.as_float = x; atom_.type = PN_FLOAT; }
-scalar::scalar(double x) { atom_.u.as_double = x; atom_.type = PN_DOUBLE; }
-scalar::scalar(amqp_timestamp x) { atom_.u.as_timestamp = x; atom_.type = PN_TIMESTAMP; }
-scalar::scalar(const amqp_decimal32& x) { atom_.u.as_decimal32 = x; atom_.type = PN_DECIMAL32; }
-scalar::scalar(const amqp_decimal64& x) { atom_.u.as_decimal64 = x; atom_.type = PN_DECIMAL64; }
-scalar::scalar(const amqp_decimal128& x) { atom_.u.as_decimal128 = x; atom_.type = PN_DECIMAL128; }
-scalar::scalar(const amqp_uuid& x) { atom_.u.as_uuid = x; atom_.type = PN_UUID; }
-
-void scalar::set(const std::string& x) { str_ = x; atom_.u.as_bytes = pn_bytes(str_); }
-scalar::scalar(const amqp_string& x) { set(x); atom_.type = PN_STRING; }
-scalar::scalar(const amqp_symbol& x) { set(x); atom_.type = PN_SYMBOL; }
-scalar::scalar(const amqp_binary& x) { set(x); atom_.type = PN_BINARY; }
-scalar::scalar(const std::string& x) { *this = amqp_string(x); }
-scalar::scalar(const char* x) { *this = amqp_string(x); }
+void scalar::set(const std::string& x, pn_type_t t) {
+ atom_.type = t;
+ str_ = x;
+ atom_.u.as_bytes = pn_bytes(str_);
+}
+
+void scalar::set(const pn_atom_t& atom) {
+ if (type_id_is_string_like(type_id(atom.type)))
+ set(str(atom.u.as_bytes), atom.type);
+ else
+ atom_ = atom;
+}
+
+scalar& scalar::operator=(bool x) { atom_.u.as_bool = x; atom_.type = PN_BOOL; return *this; }
+scalar& scalar::operator=(uint8_t x) { atom_.u.as_ubyte = x; atom_.type = PN_UBYTE; return *this; }
+scalar& scalar::operator=(int8_t x) { atom_.u.as_byte = x; atom_.type = PN_BYTE; return *this; }
+scalar& scalar::operator=(uint16_t x) { atom_.u.as_ushort = x; atom_.type = PN_USHORT; return *this; }
+scalar& scalar::operator=(int16_t x) { atom_.u.as_short = x; atom_.type = PN_SHORT; return *this; }
+scalar& scalar::operator=(uint32_t x) { atom_.u.as_uint = x; atom_.type = PN_UINT; return *this; }
+scalar& scalar::operator=(int32_t x) { atom_.u.as_int = x; atom_.type = PN_INT; return *this; }
+scalar& scalar::operator=(uint64_t x) { atom_.u.as_ulong = x; atom_.type = PN_ULONG; return *this; }
+scalar& scalar::operator=(int64_t x) { atom_.u.as_long = x; atom_.type = PN_LONG; return *this; }
+scalar& scalar::operator=(wchar_t x) { atom_.u.as_char = x; atom_.type = PN_CHAR; return *this; }
+scalar& scalar::operator=(float x) { atom_.u.as_float = x; atom_.type = PN_FLOAT; return *this; }
+scalar& scalar::operator=(double x) { atom_.u.as_double = x; atom_.type = PN_DOUBLE; return *this; }
+scalar& scalar::operator=(amqp_timestamp x) { atom_.u.as_timestamp = x; atom_.type = PN_TIMESTAMP; return *this; }
+scalar& scalar::operator=(const amqp_decimal32& x) { atom_.u.as_decimal32 = x; atom_.type = PN_DECIMAL32; return *this; }
+scalar& scalar::operator=(const amqp_decimal64& x) { atom_.u.as_decimal64 = x; atom_.type = PN_DECIMAL64; return *this; }
+scalar& scalar::operator=(const amqp_decimal128& x) { atom_.u.as_decimal128 = x; atom_.type = PN_DECIMAL128; return *this; }
+scalar& scalar::operator=(const amqp_uuid& x) { atom_.u.as_uuid = x; atom_.type = PN_UUID; return *this; }
+scalar& scalar::operator=(const amqp_string& x) { set(x, PN_STRING); return *this; }
+scalar& scalar::operator=(const amqp_symbol& x) { set(x, PN_SYMBOL); return *this; }
+scalar& scalar::operator=(const amqp_binary& x) { set(x, PN_BINARY); return *this; }
+scalar& scalar::operator=(const std::string& x) { set(x, PN_STRING); return *this; }
+scalar& scalar::operator=(const char* x) { set(x, PN_STRING); return *this; }
void scalar::ok(pn_type_t t) const {
- if (atom_.type != t) throw type_mismatch(type_id(t), type());
+ if (atom_.type != t) throw type_error(type_id(t), type());
}
void scalar::get(bool& x) const { ok(PN_BOOL); x = atom_.u.as_bool; }
@@ -75,9 +89,9 @@ void scalar::get(amqp_decimal32& x) const { ok(PN_DECIMAL32); x = atom_.u.as_dec
void scalar::get(amqp_decimal64& x) const { ok(PN_DECIMAL64); x = atom_.u.as_decimal64; }
void scalar::get(amqp_decimal128& x) const { ok(PN_DECIMAL128); x = atom_.u.as_decimal128; }
void scalar::get(amqp_uuid& x) const { ok(PN_UUID); x = atom_.u.as_uuid; }
-void scalar::get(amqp_string& x) const { ok(PN_STRING); x = str_; }
-void scalar::get(amqp_symbol& x) const { ok(PN_SYMBOL); x = str_; }
-void scalar::get(amqp_binary& x) const { ok(PN_BINARY); x = str_; }
+void scalar::get(amqp_string& x) const { ok(PN_STRING); x = amqp_string(str_); }
+void scalar::get(amqp_symbol& x) const { ok(PN_SYMBOL); x = amqp_symbol(str_); }
+void scalar::get(amqp_binary& x) const { ok(PN_BINARY); x = amqp_binary(str_); }
void scalar::get(std::string& x) const { x = get<amqp_string>(); }
int64_t scalar::as_int() const {
@@ -94,13 +108,14 @@ int64_t scalar::as_int() const {
case PN_CHAR: return atom_.u.as_char;
case PN_ULONG: return int64_t(atom_.u.as_ulong);
case PN_LONG: return atom_.u.as_long;
- default: throw type_mismatch(LONG, type(), "cannot convert");
+ case PN_TIMESTAMP: return atom_.u.as_timestamp;
+ default: throw type_error(LONG, type(), "cannot convert");
}
}
uint64_t scalar::as_uint() const {
if (!type_id_is_integral(type()))
- throw type_mismatch(ULONG, type(), "cannot convert");
+ throw type_error(ULONG, type(), "cannot convert");
return uint64_t(as_int());
}
@@ -111,18 +126,19 @@ double scalar::as_double() const {
switch (atom_.type) {
case PN_DOUBLE: return atom_.u.as_double;
case PN_FLOAT: return atom_.u.as_float;
- default: throw type_mismatch(DOUBLE, type(), "cannot convert");
+ default: throw type_error(DOUBLE, type(), "cannot convert");
}
}
std::string scalar::as_string() const {
if (type_id_is_string_like(type()))
return str_;
- throw type_mismatch(DOUBLE, type(), "cannot convert");
+ throw type_error(STRING, type(), "cannot convert");
}
-
namespace {
+template<class T> int opaque_cmp(const T& x, const T& y) { return memcmp(&x, &y, sizeof(T)); }
+
template <class T, class F> T type_switch(const scalar& a, F f) {
switch(a.type()) {
case BOOLEAN: return f(a.get<bool>());
@@ -170,16 +186,21 @@ struct ostream_op {
} // namespace
-bool scalar::operator==(const scalar& x) const {
- return type_switch<bool>(*this, equal_op(x));
+bool operator==(const scalar& x, const scalar& y) {
+ if (x.type() != y.type()) return false;
+ if (x.empty()) return true;
+ return type_switch<bool>(x, equal_op(y));
}
-bool scalar::operator<(const scalar& x) const {
- return type_switch<bool>(*this, less_op(x));
+bool operator<(const scalar& x, const scalar& y) {
+ if (x.type() != y.type()) return x.type() < y.type();
+ if (x.empty()) return false;
+ return type_switch<bool>(x, less_op(y));
}
std::ostream& operator<<(std::ostream& o, const scalar& a) {
+ if (a.empty()) return o << "<null>";
return type_switch<std::ostream&>(a, ostream_op(o));
}
-}
+} // namespace proton
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/1622d0e6/proton-c/bindings/cpp/src/scalar_test.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/scalar_test.cpp b/proton-c/bindings/cpp/src/scalar_test.cpp
index c7de785..cb66e41 100644
--- a/proton-c/bindings/cpp/src/scalar_test.cpp
+++ b/proton-c/bindings/cpp/src/scalar_test.cpp
@@ -21,51 +21,62 @@
#include "proton/type_traits.hpp"
#include <proton/scalar.hpp>
+#include <proton/value.hpp>
+#include <proton/message_id.hpp>
+#include <proton/annotation_key.hpp>
+
+#include <sstream>
using namespace std;
using namespace proton;
// Inserting and extracting simple C++ values.
template <class T> void type_test(T x, type_id tid, T y) {
- scalar v(x);
- ASSERT_EQUAL(tid, v.type());
- ASSERT(!v.empty());
- ASSERT_EQUAL(x, v.get<T>());
+ scalar s(x);
+ ASSERT_EQUAL(tid, s.type());
+ ASSERT(!s.empty());
+ ASSERT_EQUAL(x, s.get<T>());
scalar v2;
ASSERT(v2.type() == NULL_TYPE);
v2 = x;
ASSERT_EQUAL(tid, v2.type());
ASSERT_EQUAL(x, v2.get<T>());
- ASSERT_EQUAL(v, v2);
- ASSERT_EQUAL(str(x), str(v));
+ ASSERT_EQUAL(s, v2);
+ ASSERT_EQUAL(str(x), str(s));
v2 = y;
- ASSERT(v != v2);
- ASSERT(v < v2);
- ASSERT(v2 > v);
+ ASSERT(s != v2);
+ ASSERT(s < v2);
+ ASSERT(v2 > s);
}
-#define ASSERT_MISMATCH(EXPR) \
- try { (void)(EXPR); FAIL("expected type_mismatch: " #EXPR); } catch (type_mismatch) {}
+#define ASSERT_MISMATCH(EXPR, WANT, GOT) \
+ try { \
+ (void)(EXPR); \
+ FAIL("expected type_error: " #EXPR); \
+ } catch (const type_error& e) { \
+ ASSERT_EQUAL(WANT, e.want); \
+ ASSERT_EQUAL(GOT, e.got); \
+ }
void convert_test() {
scalar a;
ASSERT_EQUAL(NULL_TYPE, a.type());
ASSERT(a.empty());
- ASSERT_MISMATCH(a.get<float>());
+ ASSERT_MISMATCH(a.get<float>(), FLOAT, NULL_TYPE);
a = amqp_binary("foo");
- ASSERT_MISMATCH(a.get<int16_t>());
- ASSERT_MISMATCH(a.as_int());
- ASSERT_MISMATCH(a.as_double());
- ASSERT_MISMATCH(a.get<amqp_string>()); // No strict conversion
+ ASSERT_MISMATCH(a.get<int16_t>(), SHORT, BINARY);
+ ASSERT_MISMATCH(a.as_int(), LONG, BINARY);
+ ASSERT_MISMATCH(a.as_double(), DOUBLE, BINARY);
+ ASSERT_MISMATCH(a.get<amqp_string>(), STRING, BINARY); // No strict conversion
ASSERT_EQUAL(a.as_string(), std::string("foo")); // OK string-like conversion
a = int16_t(42);
- ASSERT_MISMATCH(a.get<std::string>());
- ASSERT_MISMATCH(a.get<amqp_timestamp>());
- ASSERT_MISMATCH(a.as_string());
+ ASSERT_MISMATCH(a.get<std::string>(), STRING, SHORT);
+ ASSERT_MISMATCH(a.get<amqp_timestamp>(), TIMESTAMP, SHORT);
+ ASSERT_MISMATCH(a.as_string(), STRING, SHORT);
ASSERT_EQUAL(a.as_int(), 42);
ASSERT_EQUAL(a.as_uint(), 42);
ASSERT_EQUAL(a.as_double(), 42);
@@ -76,6 +87,33 @@ void convert_test() {
ASSERT_EQUAL(a.as_double(), -42);
}
+void encode_decode_test() {
+ value v;
+ scalar a("foo");
+ v = a; // Assignment to value does encode, get<> does decode.
+ ASSERT_EQUAL(v, a);
+ ASSERT_EQUAL(std::string("foo"), v.get<std::string>());
+ scalar a2 = v.get<scalar>();
+ ASSERT_EQUAL(std::string("foo"), a2.get<std::string>());
+}
+
+void message_id_test() {
+ ASSERT_EQUAL(23, message_id(23).as_int());
+ ASSERT_EQUAL(23, message_id(23).get<uint64_t>());
+ ASSERT(message_id("foo") != message_id(amqp_binary("foo")));
+ ASSERT_EQUAL(scalar("foo"), message_id("foo"));
+ ASSERT_EQUAL("foo", message_id("foo").as_string());
+ ASSERT(message_id("a") < message_id("z"));
+ ASSERT_EQUAL(amqp_uuid(), message_id(amqp_uuid()).get<amqp_uuid>());
+}
+
+void annotation_key_test() {
+ ASSERT_EQUAL(23, annotation_key(23).as_int());
+ ASSERT_EQUAL(23, annotation_key(23).get<uint64_t>());
+ ASSERT_EQUAL("foo", annotation_key("foo").as_string());
+ ASSERT_EQUAL(scalar(amqp_symbol("foo")), annotation_key("foo"));
+}
+
int main(int, char**) {
int failed = 0;
RUN_TEST(failed, type_test(false, BOOLEAN, true));
@@ -101,5 +139,9 @@ int main(int, char**) {
RUN_TEST(failed, type_test(amqp_symbol("aaa"), SYMBOL, amqp_symbol("aaaa")));
RUN_TEST(failed, type_test(amqp_binary("aaa"), BINARY, amqp_binary("aaaa")));
RUN_TEST(failed, type_test(std::string("xxx"), STRING, std::string("yyy")));
+ RUN_TEST(failed, encode_decode_test());
+ RUN_TEST(failed, message_id_test());
+ RUN_TEST(failed, annotation_key_test());
+ RUN_TEST(failed, convert_test());
return failed;
}
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/1622d0e6/proton-c/bindings/cpp/src/types.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/types.cpp b/proton-c/bindings/cpp/src/types.cpp
index fa7b0bd..7a38f12 100644
--- a/proton-c/bindings/cpp/src/types.cpp
+++ b/proton-c/bindings/cpp/src/types.cpp
@@ -33,20 +33,18 @@ inline std::ostream& print_segment(std::ostream& o, const amqp_uuid& u, size_t b
return o << sep;
}
-std::string mismatch_message(type_id want, type_id got, const std::string& msg=std::string())
-{
+std::string mismatch_message(type_id want, type_id got, const std::string& msg=std::string()) {
std::ostringstream s;
- s << "type mismatch: want " << type_name(want) << " got " << type_name(got);
+ s << "want " << want << " got " << got;
if (!msg.empty()) s << ": " << msg;
return s.str();
}
-}
+} // namespace
-type_mismatch::type_mismatch(type_id want_, type_id got_, const std::string &msg)
- : error(mismatch_message(want_, got_, msg)), want(want_), got(got_)
+type_error::type_error(type_id want_, type_id got_, const std::string &msg)
+ : decode_error(mismatch_message(want_, got_, msg)), want(want_), got(got_)
{}
-
std::ostream& operator<<(std::ostream& o, const amqp_decimal32&) { return o << "<decimal32>"; }
std::ostream& operator<<(std::ostream& o, const amqp_decimal64&) { return o << "<decimal64>"; }
std::ostream& operator<<(std::ostream& o, const amqp_decimal128&) { return o << "<decimal128>"; }
@@ -95,9 +93,9 @@ std::string type_name(type_id t) {
return "unknown";
}
-static bool type_id_is_signed_int(type_id t) { return t == BYTE || t == SHORT || t == INT || t == LONG; }
-static bool type_id_is_unsigned_int(type_id t) { return t == UBYTE || t == USHORT || t == UINT || t == ULONG; }
-bool type_id_is_integral(type_id t) { return t == BOOLEAN || t == CHAR || type_id_is_unsigned_int(t) || type_id_is_signed_int(t); }
+bool type_id_is_signed_int(type_id t) { return t == BYTE || t == SHORT || t == INT || t == LONG; }
+bool type_id_is_unsigned_int(type_id t) { return t == UBYTE || t == USHORT || t == UINT || t == ULONG; }
+bool type_id_is_integral(type_id t) { return t == BOOLEAN || t == CHAR || t == TIMESTAMP || type_id_is_unsigned_int(t) || type_id_is_signed_int(t); }
bool type_id_is_floating_point(type_id t) { return t == FLOAT || t == DOUBLE; }
bool type_id_is_decimal(type_id t) { return t == DECIMAL32 || t == DECIMAL64 || t == DECIMAL128; }
bool type_id_is_signed(type_id t) { return type_id_is_signed_int(t) || type_id_is_floating_point(t) || type_id_is_decimal(t); }
@@ -106,7 +104,7 @@ bool type_id_is_container(type_id t) { return t == LIST || t == MAP || t == ARRA
bool type_id_is_scalar(type_id t) { return type_id_is_integral(t) || type_id_is_floating_point(t) || type_id_is_decimal(t) || type_id_is_string_like(t) || t == TIMESTAMP || t == UUID; }
-std::ostream& operator<<(std::ostream& o,type_id t) { return o << type_name(t); }
+std::ostream& operator<<(std::ostream& o, type_id t) { return o << type_name(t); }
pn_bytes_t pn_bytes(const std::string& s) {
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/1622d0e6/proton-c/bindings/cpp/src/value.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/value.cpp b/proton-c/bindings/cpp/src/value.cpp
index b603bf9..bf652c5 100644
--- a/proton-c/bindings/cpp/src/value.cpp
+++ b/proton-c/bindings/cpp/src/value.cpp
@@ -30,8 +30,20 @@ value::value() : data_(data::create()) {}
value::value(const value& x) : data_(data::create()) { data_.copy(x.data_); }
+#if PN_HAS_CPP11
+value::value(value&& x) : data_(0) { swap(x); }
+#endif
+
+// Referencing an external value
+value::value(data d) : data_(d) {}
+
+// Referencing an external value
+value& value::ref(data d) { data_ = d; return *this; }
+
value& value::operator=(const value& x) { data_.copy(x.data_); return *this; }
+void value::swap(value& x) { std::swap(data_, x.data_); }
+
void value::clear() { data_.clear(); }
bool value::empty() const { return data_.empty(); }
@@ -48,6 +60,8 @@ bool value::operator<(const value& x) const { return data_.less(x.data_); }
std::ostream& operator<<(std::ostream& o, const value& v) {
// pn_inspect prints strings with quotes which is not normal in C++.
+ if (v.empty())
+ return o << "<empty>";
switch (v.type()) {
case STRING:
case SYMBOL:
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org
[4/4] qpid-proton git commit: PROTON-1085: c++: Replace all
operator== and < members with free functions, drop comparable template.
Posted by ac...@apache.org.
PROTON-1085: c++: Replace all operator== and < members with free functions, drop comparable template.
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/117bb7cb
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/117bb7cb
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/117bb7cb
Branch: refs/heads/master
Commit: 117bb7cb0bcb588f91c8a2a6a45b0cb9d211d7d6
Parents: 1622d0e
Author: Alan Conway <ac...@redhat.com>
Authored: Tue Dec 29 13:54:02 2015 -0500
Committer: Alan Conway <ac...@redhat.com>
Committed: Tue Dec 29 15:56:44 2015 -0500
----------------------------------------------------------------------
.../bindings/cpp/include/proton/comparable.hpp | 38 --------------------
.../bindings/cpp/include/proton/duration.hpp | 8 ++---
proton-c/bindings/cpp/include/proton/object.hpp | 5 ++-
proton-c/bindings/cpp/include/proton/scalar.hpp | 6 ++--
proton-c/bindings/cpp/include/proton/types.hpp | 15 ++++----
proton-c/bindings/cpp/include/proton/value.hpp | 8 ++---
proton-c/bindings/cpp/src/scalar.cpp | 1 -
proton-c/bindings/cpp/src/value.cpp | 4 +--
8 files changed, 21 insertions(+), 64 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/117bb7cb/proton-c/bindings/cpp/include/proton/comparable.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/comparable.hpp b/proton-c/bindings/cpp/include/proton/comparable.hpp
deleted file mode 100644
index 2649a8d..0000000
--- a/proton-c/bindings/cpp/include/proton/comparable.hpp
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef COMPARABLE_HPP
-#define COMPARABLE_HPP
-/*
- * 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.
- */
-
-namespace proton {
-
-///@cond INTERNAL
-
-/// Internal base class to provide comparison operators. T must provide < and ==.
-template <class T> struct comparable {
- friend bool operator>(const T &a, const T &b) { return b < a; }
- friend bool operator<=(const T &a, const T &b) { return !(a > b); }
- friend bool operator>=(const T &a, const T &b) { return !(a < b); }
- friend bool operator!=(const T &a, const T &b) { return !(a == b); }
-};
-
-///@endcond
-
-}
-
-#endif // COMPARABLE_HPP
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/117bb7cb/proton-c/bindings/cpp/include/proton/duration.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/duration.hpp b/proton-c/bindings/cpp/include/proton/duration.hpp
index e562c47..cea785f 100644
--- a/proton-c/bindings/cpp/include/proton/duration.hpp
+++ b/proton-c/bindings/cpp/include/proton/duration.hpp
@@ -28,21 +28,21 @@
namespace proton {
/** Duration in milliseconds. */
-class duration : public comparable<duration>
+class duration
{
public:
amqp_ulong milliseconds;
explicit duration(amqp_ulong ms = 0) : milliseconds(ms) {}
- bool operator<(duration d) { return milliseconds < d.milliseconds; }
- bool operator==(duration d) { return milliseconds == d.milliseconds; }
-
PN_CPP_EXTERN static const duration FOREVER; ///< Wait for ever
PN_CPP_EXTERN static const duration IMMEDIATE; ///< Don't wait at all
PN_CPP_EXTERN static const duration SECOND; ///< One second
PN_CPP_EXTERN static const duration MINUTE; ///< One minute
};
+inline bool operator<(duration x, duration y) { return x.milliseconds < y.milliseconds; }
+inline bool operator==(duration x, duration y) { return x.milliseconds == y.milliseconds; }
+
inline duration operator*(duration d, amqp_ulong n) { return duration(d.milliseconds*n); }
inline duration operator*(amqp_ulong n, duration d) { return d * n; }
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/117bb7cb/proton-c/bindings/cpp/include/proton/object.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/object.hpp b/proton-c/bindings/cpp/include/proton/object.hpp
index e98a956..32bc086 100644
--- a/proton-c/bindings/cpp/include/proton/object.hpp
+++ b/proton-c/bindings/cpp/include/proton/object.hpp
@@ -21,7 +21,6 @@
#include "proton/config.hpp"
#include "proton/export.hpp"
-#include "proton/comparable.hpp"
#include <memory>
@@ -34,7 +33,7 @@ class pn_ptr_base {
PN_CPP_EXTERN static void decref(void* p);
};
-template <class T> class pn_ptr : public comparable<pn_ptr<T> >, private pn_ptr_base {
+template <class T> class pn_ptr : private pn_ptr_base {
public:
pn_ptr() : ptr_(0) {}
pn_ptr(T* p) : ptr_(p) { incref(ptr_); }
@@ -71,7 +70,7 @@ template <class T> pn_ptr<T> take_ownership(T* p) { return pn_ptr<T>::take_owner
/**
* Base class for proton object types
*/
-template <class T> class object : public comparable<object<T> > {
+template <class T> class object {
public:
bool operator!() const { return !object_; }
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/117bb7cb/proton-c/bindings/cpp/include/proton/scalar.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/scalar.hpp b/proton-c/bindings/cpp/include/proton/scalar.hpp
index 6fe29fa..d135ab6 100644
--- a/proton-c/bindings/cpp/include/proton/scalar.hpp
+++ b/proton-c/bindings/cpp/include/proton/scalar.hpp
@@ -29,7 +29,7 @@ class encoder;
class decoder;
/** scalar holds an instance of any scalar AMQP type. */
-class scalar : public comparable<scalar> {
+class scalar {
public:
PN_CPP_EXTERN scalar();
PN_CPP_EXTERN scalar(const scalar&);
@@ -130,9 +130,9 @@ class scalar : public comparable<scalar> {
};
///@internal base for restricted scalar types
-class restricted_scalar : public comparable<restricted_scalar> {
+class restricted_scalar {
public:
- operator scalar() const { return scalar_; }
+ operator const scalar&() const { return scalar_; }
type_id type() const { return scalar_.type(); }
///@name as_ methods do "loose" conversion, they will convert the scalar's
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/117bb7cb/proton-c/bindings/cpp/include/proton/types.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/types.hpp b/proton-c/bindings/cpp/include/proton/types.hpp
index db5989b..062566a 100644
--- a/proton-c/bindings/cpp/include/proton/types.hpp
+++ b/proton-c/bindings/cpp/include/proton/types.hpp
@@ -25,7 +25,6 @@
#include "proton/export.hpp"
#include "proton/error.hpp"
-#include "proton/comparable.hpp"
#include <proton/codec.h>
#include <proton/type_compat.h>
@@ -141,7 +140,7 @@ struct amqp_binary : public std::string {
};
/// Template for opaque proton proton types that can be treated as byte arrays.
-template <class P> struct opaque: public comparable<opaque<P> > {
+template <class P> struct opaque {
P value;
opaque(const P& p=P()) : value(p) {}
operator P() const { return value; }
@@ -153,11 +152,11 @@ template <class P> struct opaque: public comparable<opaque<P> > {
const char* end() const { return reinterpret_cast<const char*>(&value)+size(); }
char& operator[](size_t i) { return *(begin()+i); }
const char& operator[](size_t i) const { return *(begin()+i); }
-
- bool operator==(const opaque& x) const { return std::equal(begin(), end(), x.begin()); }
- bool operator<(const opaque& x) const { return std::lexicographical_compare(begin(), end(), x.begin(), x.end()); }
};
+template <class T> bool operator==(const opaque<T>& x, const opaque<T>& y) { return std::equal(x.begin(), x.end(), y.begin()); }
+template <class T> bool operator<(const opaque<T>& x, const opaque<T>& y) { return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
+
/// AMQP 16-byte UUID.
typedef opaque<pn_uuid_t> amqp_uuid;
PN_CPP_EXTERN std::ostream& operator<<(std::ostream&, const amqp_uuid&);
@@ -172,13 +171,13 @@ typedef opaque<pn_decimal128_t> amqp_decimal128;
PN_CPP_EXTERN std::ostream& operator<<(std::ostream&, const amqp_decimal128&);
/// AMQP timestamp, milliseconds since the epoch 00:00:00 (UTC), 1 January 1970.
-struct amqp_timestamp : public comparable<amqp_timestamp> {
+struct amqp_timestamp {
pn_timestamp_t milliseconds;
amqp_timestamp(::int64_t ms=0) : milliseconds(ms) {}
operator pn_timestamp_t() const { return milliseconds; }
- bool operator==(const amqp_timestamp& x) { return milliseconds == x.milliseconds; }
- bool operator<(const amqp_timestamp& x) { return milliseconds < x.milliseconds; }
};
+inline bool operator==(amqp_timestamp x, amqp_timestamp y) { return x.milliseconds == y.milliseconds; }
+inline bool operator<(amqp_timestamp x, amqp_timestamp y) { return x.milliseconds < y.milliseconds; }
PN_CPP_EXTERN std::ostream& operator<<(std::ostream&, const amqp_timestamp&);
// TODO aconway 2015-06-16: described types.
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/117bb7cb/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 dedcadd..1ecaaa5 100644
--- a/proton-c/bindings/cpp/include/proton/value.hpp
+++ b/proton-c/bindings/cpp/include/proton/value.hpp
@@ -40,7 +40,7 @@ class decoder;
* Assigning to a proton::value follows the encoder rules, converting from a
* proton::value (or calling proton::value::get) follows the decoder rules.
*/
-class value : public comparable<value> {
+class value {
public:
PN_CPP_EXTERN value();
PN_CPP_EXTERN value(const value&);
@@ -73,12 +73,10 @@ class value : public comparable<value> {
/** Get the value. */
template<class T> T get() const { T t; get(t); return t; }
- // FIXME aconway 2015-12-28: friend ops.
- PN_CPP_EXTERN bool operator==(const value& x) const;
- PN_CPP_EXTERN bool operator<(const value& x) const;
-
PN_CPP_EXTERN void swap(value& v);
+ friend PN_CPP_EXTERN bool operator==(const value& x, const value& y);
+ friend PN_CPP_EXTERN bool operator<(const value& x, const value& y);
friend PN_CPP_EXTERN class encoder operator<<(class encoder e, const value& dv);
friend PN_CPP_EXTERN class decoder operator>>(class decoder d, value& dv);
friend PN_CPP_EXTERN std::ostream& operator<<(std::ostream& o, const value& dv);
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/117bb7cb/proton-c/bindings/cpp/src/scalar.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/scalar.cpp b/proton-c/bindings/cpp/src/scalar.cpp
index 9e8d124..d52c8eb 100644
--- a/proton-c/bindings/cpp/src/scalar.cpp
+++ b/proton-c/bindings/cpp/src/scalar.cpp
@@ -137,7 +137,6 @@ std::string scalar::as_string() const {
}
namespace {
-template<class T> int opaque_cmp(const T& x, const T& y) { return memcmp(&x, &y, sizeof(T)); }
template <class T, class F> T type_switch(const scalar& a, F f) {
switch(a.type()) {
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/117bb7cb/proton-c/bindings/cpp/src/value.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/value.cpp b/proton-c/bindings/cpp/src/value.cpp
index bf652c5..9e8448c 100644
--- a/proton-c/bindings/cpp/src/value.cpp
+++ b/proton-c/bindings/cpp/src/value.cpp
@@ -54,9 +54,9 @@ class decoder value::decoder() const { data_.decoder().rewind(); return data_.de
type_id value::type() const { return decoder().type(); }
-bool value::operator==(const value& x) const { return data_.equal(x.data_); }
+bool operator==(const value& x, const value& y) { return x.data_.equal(y.data_); }
-bool value::operator<(const value& x) const { return data_.less(x.data_); }
+bool operator<(const value& x, const value& y) { return x.data_.less(y.data_); }
std::ostream& operator<<(std::ostream& o, const value& v) {
// pn_inspect prints strings with quotes which is not normal in C++.
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org
[3/4] qpid-proton git commit: PROTON-1085: c++: clean up access to
message properties, instructions and annotations.
Posted by ac...@apache.org.
PROTON-1085: c++: clean up access to message properties, instructions and annotations.
- Use proton::value& as message::body() type.
- Create pn_message on demand for empty message.
- Use proton::scalar as basis for messsage_id and annotation_key
- message_id restricted to be one of: uint64_t, amqp_uuid, amqp_binary or amqp_string.
- annotation_key restricted to be on of: uint64_t or amqp_symbol.
- Decode and cache application properties, annotations and instructions on demand as std::map.
- message::properties() returns std::map<std::string, scalar>&
- message::instructions()/annotations() returns std::map<annotation_key, value>&
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/1622d0e6
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/1622d0e6
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/1622d0e6
Branch: refs/heads/master
Commit: 1622d0e608738da7b603b7e497bc3a8166325865
Parents: d2c5a5f
Author: Alan Conway <ac...@redhat.com>
Authored: Fri Dec 18 09:33:58 2015 -0500
Committer: Alan Conway <ac...@redhat.com>
Committed: Tue Dec 29 15:56:44 2015 -0500
----------------------------------------------------------------------
examples/cpp/client.cpp | 2 +-
examples/cpp/example_test.py | 18 +-
proton-c/CMakeLists.txt | 2 +-
.../cpp/include/proton/annotation_key.hpp | 58 +++++
proton-c/bindings/cpp/include/proton/data.hpp | 2 -
.../bindings/cpp/include/proton/decoder.hpp | 27 +--
.../bindings/cpp/include/proton/encoder.hpp | 26 +-
proton-c/bindings/cpp/include/proton/error.hpp | 6 +
.../bindings/cpp/include/proton/message.hpp | 81 +++----
.../bindings/cpp/include/proton/message_id.hpp | 67 ++---
proton-c/bindings/cpp/include/proton/scalar.hpp | 117 +++++----
proton-c/bindings/cpp/include/proton/ssl.hpp | 2 +-
.../bindings/cpp/include/proton/type_traits.hpp | 2 +-
proton-c/bindings/cpp/include/proton/types.hpp | 77 +++---
proton-c/bindings/cpp/include/proton/value.hpp | 16 +-
proton-c/bindings/cpp/src/decoder.cpp | 138 ++++++-----
.../bindings/cpp/src/encode_decode_test.cpp | 39 ++-
proton-c/bindings/cpp/src/encoder.cpp | 56 +++--
proton-c/bindings/cpp/src/error.cpp | 2 +
proton-c/bindings/cpp/src/event.cpp | 2 +-
proton-c/bindings/cpp/src/message.cpp | 242 ++++++++-----------
proton-c/bindings/cpp/src/message_test.cpp | 102 +++++---
proton-c/bindings/cpp/src/scalar.cpp | 97 +++++---
proton-c/bindings/cpp/src/scalar_test.cpp | 80 ++++--
proton-c/bindings/cpp/src/types.cpp | 20 +-
proton-c/bindings/cpp/src/value.cpp | 14 ++
26 files changed, 751 insertions(+), 544 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/1622d0e6/examples/cpp/client.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/client.cpp b/examples/cpp/client.cpp
index 4dee119..3f5c4ab 100644
--- a/examples/cpp/client.cpp
+++ b/examples/cpp/client.cpp
@@ -58,7 +58,7 @@ class client : public proton::messaging_handler {
void on_message(proton::event &e) {
if (requests.empty()) return; // Spurious extra message!
proton::message& response = e.message();
- std::cout << '"' << requests.front() << '"' << " => " << response.body() << std::endl;
+ std::cout << requests.front() << " => " << response.body() << std::endl;
requests.erase(requests.begin());
if (!requests.empty()) {
send_request();
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/1622d0e6/examples/cpp/example_test.py
----------------------------------------------------------------------
diff --git a/examples/cpp/example_test.py b/examples/cpp/example_test.py
index 1f800c0..c1e7ac5 100644
--- a/examples/cpp/example_test.py
+++ b/examples/cpp/example_test.py
@@ -125,17 +125,17 @@ class ExampleTest(unittest.TestCase):
def test_helloworld(self):
b = Broker.get()
hw = execute("helloworld", b.addr)
- self.assertEqual('"Hello World!"\n', hw)
+ self.assertEqual('Hello World!\n', hw)
def test_helloworld_blocking(self):
b = Broker.get()
hw = execute("helloworld_blocking", b.addr)
- self.assertEqual('"Hello World!"\n', hw)
+ self.assertEqual('Hello World!\n', hw)
def test_helloworld_direct(self):
addr = pick_addr()
hw = execute("helloworld_direct", addr)
- self.assertEqual('"Hello World!"\n', hw)
+ self.assertEqual('Hello World!\n', hw)
def test_simple_send_recv(self):
b = Broker.get()
@@ -165,10 +165,10 @@ class ExampleTest(unittest.TestCase):
send_expect = "direct_send listening on amqp://%s\nall messages confirmed\n" % (addr)
self.assertEqual(send_expect, verify(send))
- CLIENT_EXPECT=""""Twas brillig, and the slithy toves" => "TWAS BRILLIG, AND THE SLITHY TOVES"
-"Did gire and gymble in the wabe." => "DID GIRE AND GYMBLE IN THE WABE."
-"All mimsy were the borogroves," => "ALL MIMSY WERE THE BOROGROVES,"
-"And the mome raths outgrabe." => "AND THE MOME RATHS OUTGRABE."
+ CLIENT_EXPECT="""Twas brillig, and the slithy toves => TWAS BRILLIG, AND THE SLITHY TOVES
+Did gire and gymble in the wabe. => DID GIRE AND GYMBLE IN THE WABE.
+All mimsy were the borogroves, => ALL MIMSY WERE THE BOROGROVES,
+And the mome raths outgrabe. => AND THE MOME RATHS OUTGRABE.
"""
def test_simple_recv_send(self):
# Start receiver first, then run sender"""
@@ -247,7 +247,7 @@ Tock...
def test_ssl(self):
# SSL without SASL
expect="""Outgoing client connection connected via SSL. Server certificate identity CN=test_server
-"Hello World!"
+Hello World!
"""
addr = "amqps://" + pick_addr() + "/examples"
ignore_first_line, ignore_nl, ssl_hw = execute("ssl", addr, ssl_certs_dir()).partition('\n')
@@ -257,7 +257,7 @@ Tock...
# SSL with SASL EXTERNAL
expect="""Inbound client certificate identity CN=test_client
Outgoing client connection connected via SSL. Server certificate identity CN=test_server
-"Hello World!"
+Hello World!
"""
addr = "amqps://" + pick_addr() + "/examples"
ignore_first_line, ignore_nl, ssl_hw = execute("ssl_client_cert", addr, ssl_certs_dir()).partition('\n')
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/1622d0e6/proton-c/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/CMakeLists.txt b/proton-c/CMakeLists.txt
index 3d2f457..b645563 100644
--- a/proton-c/CMakeLists.txt
+++ b/proton-c/CMakeLists.txt
@@ -246,7 +246,7 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
if (ENABLE_WARNING_ERROR)
set (WERROR "-Werror")
endif (ENABLE_WARNING_ERROR)
- set (CXX_WARNING_FLAGS "${WERROR} -pedantic -Weverything -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-float-equal -Wno-padded -Wno-sign-conversion -Wno-switch-enum -Wno-weak-vtables -Wno-exit-time-destructors -Wno-global-constructors -Wno-shorten-64-to-32")
+ set (CXX_WARNING_FLAGS "${WERROR} -pedantic -Weverything -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-float-equal -Wno-padded -Wno-sign-conversion -Wno-switch-enum -Wno-weak-vtables -Wno-exit-time-destructors -Wno-global-constructors -Wno-shorten-64-to-32 -Wno-documentation -Wno-documentation-unknown-command")
endif()
if (MSVC)
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/1622d0e6/proton-c/bindings/cpp/include/proton/annotation_key.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/annotation_key.hpp b/proton-c/bindings/cpp/include/proton/annotation_key.hpp
new file mode 100644
index 0000000..edd63b1
--- /dev/null
+++ b/proton-c/bindings/cpp/include/proton/annotation_key.hpp
@@ -0,0 +1,58 @@
+#ifndef ANNOTATION_KEY_HPP
+#define ANNOTATION_KEY_HPP
+/*
+ * 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/types.hpp"
+#include "proton/scalar.hpp"
+
+namespace proton {
+class encoder;
+class decoder;
+
+/** An annotation_key can contain one of the following types: uint64_t or amqp_symbol. */
+class annotation_key : public restricted_scalar {
+ public:
+ annotation_key() { scalar_ = uint64_t(0); }
+
+ ///@name Assign a C++ value, deduce the AMQP type()
+ ///@{
+ annotation_key& operator=(uint64_t x) { scalar_ = x; return *this; }
+ annotation_key& operator=(const amqp_symbol& x) { scalar_ = x; return *this; }
+ /// std::string is encoded as amqp_symbol
+ annotation_key& operator=(const std::string& x) { scalar_ = amqp_symbol(x); return *this; }
+ /// char* is encoded as amqp_symbol
+ annotation_key& operator=(const char *x) { scalar_ = amqp_symbol(x); return *this; }
+ ///@}
+
+ /// Converting constructor from any type that we can assign from.
+ template <class T> annotation_key(T x) { *this = x; }
+
+ void get(uint64_t& x) const { scalar_.get(x); }
+ void get(amqp_symbol& x) const { scalar_.get(x); }
+
+ template<class T> T get() const { T x; get(x); return x; }
+
+ friend PN_CPP_EXTERN encoder operator<<(encoder, const annotation_key&);
+ friend PN_CPP_EXTERN decoder operator>>(decoder, annotation_key&);
+ friend class message;
+};
+
+}
+#endif // ANNOTATION_KEY_HPP
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/1622d0e6/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 37e1a61..7581ac7 100644
--- a/proton-c/bindings/cpp/include/proton/data.hpp
+++ b/proton-c/bindings/cpp/include/proton/data.hpp
@@ -39,8 +39,6 @@ class data;
class data : public object<pn_data_t> {
public:
data(pn_data_t* d) : object<pn_data_t>(d) {}
- data(const data& d) : object<pn_data_t>(d) {}
- data& operator=(const data&);
PN_CPP_EXTERN static data create();
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/1622d0e6/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 3073989..5dae3c3 100644
--- a/proton-c/bindings/cpp/include/proton/decoder.hpp
+++ b/proton-c/bindings/cpp/include/proton/decoder.hpp
@@ -44,11 +44,11 @@ struct pn_data_t;
namespace proton {
+class scalar;
class data;
class message_id;
-
-/** Raised by decoder operations on error.*/
-struct decode_error : public error { PN_CPP_EXTERN explicit decode_error(const std::string&); };
+class annotation_key;
+class value;
/** Skips a value with `dec >> skip()`. */
struct skip{};
@@ -208,7 +208,9 @@ class decoder : public object<pn_data_t> {
PN_CPP_EXTERN friend decoder operator>>(decoder, amqp_uuid&);
PN_CPP_EXTERN friend decoder operator>>(decoder, std::string&);
PN_CPP_EXTERN friend decoder operator>>(decoder, message_id&);
+ PN_CPP_EXTERN friend decoder operator>>(decoder, annotation_key&);
PN_CPP_EXTERN friend decoder operator>>(decoder, value&);
+ PN_CPP_EXTERN friend decoder operator>>(decoder, scalar&);
///@}
/** Extract and return a value of type T. */
@@ -256,8 +258,6 @@ class decoder : public object<pn_data_t> {
private:
PN_CPP_EXTERN void check_type(type_id);
-
- friend class encoder;
};
/** Call decoder::start() in constructor, decoder::finish in destructor().
@@ -280,20 +280,13 @@ operator>>(decoder d, T& i) {
}
///@cond INTERNAL
-template <class T> struct sequence_ref {
- sequence_ref(T& v) : value(v) {}
- T& value;
-};
-
-template <class T> struct map_ref {
- map_ref(T& v) : value(v) {}
- T& value;
-};
-
-template <class T> struct pairs_ref {
- pairs_ref(T& v) : value(v) {}
+template <class T> struct ref {
+ ref(T& v) : value(v) {}
T& value;
};
+template <class T> struct sequence_ref : public ref<T> { sequence_ref(T& v) : ref<T>(v) {} };
+template <class T> struct map_ref : public ref<T> { map_ref(T& v) : ref<T>(v) {} };
+template <class T> struct pairs_ref : public ref<T> { pairs_ref(T& v) : ref<T>(v) {} };
///@endcond
/**
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/1622d0e6/proton-c/bindings/cpp/include/proton/encoder.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/encoder.hpp b/proton-c/bindings/cpp/include/proton/encoder.hpp
index 940064d..e521922 100644
--- a/proton-c/bindings/cpp/include/proton/encoder.hpp
+++ b/proton-c/bindings/cpp/include/proton/encoder.hpp
@@ -44,11 +44,31 @@ struct pn_data_t;
namespace proton {
+class scalar;
class data;
class message_id;
+class annotation_key;
+class value;
-/** Raised by encoder operations on error */
-struct encode_error : public error { PN_CPP_EXTERN explicit encode_error(const std::string&); };
+///@cond INTERNAL
+template<class T, type_id A> struct cref {
+ typedef T cpp_type;
+ static const type_id type;
+
+ cref(const T& v) : value(v) {}
+ const T& value;
+};
+template <class T, type_id A> const type_id cref<T, A>::type = A;
+///@endcond INTERNAL
+
+/**
+ * Indicate the desired AMQP type to use when encoding T.
+ * For example to encode a vector as a list:
+ *
+ * std::vector<amqp_int> v;
+ * encoder << as<LIST>(v);
+ */
+template <type_id A, class T> cref<T, A> as(const T& value) { return cref<T, A>(value); }
/**
* Stream-like encoder from C++ values to AMQP values.
@@ -139,7 +159,9 @@ class encoder : public object<pn_data_t> {
friend PN_CPP_EXTERN encoder operator<<(encoder, amqp_symbol);
friend PN_CPP_EXTERN encoder operator<<(encoder, amqp_binary);
friend PN_CPP_EXTERN encoder operator<<(encoder, const message_id&);
+ friend PN_CPP_EXTERN encoder operator<<(encoder, const annotation_key&);
friend PN_CPP_EXTERN encoder operator<<(encoder, const value&);
+ friend PN_CPP_EXTERN encoder operator<<(encoder, const scalar&);
///@}
/**
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/1622d0e6/proton-c/bindings/cpp/include/proton/error.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/error.hpp b/proton-c/bindings/cpp/include/proton/error.hpp
index d2f57c6..f3475cf 100644
--- a/proton-c/bindings/cpp/include/proton/error.hpp
+++ b/proton-c/bindings/cpp/include/proton/error.hpp
@@ -34,6 +34,12 @@ struct error : public std::runtime_error { PN_CPP_EXTERN explicit error(const st
/** Raised if timeout expires */
struct timeout_error : public error { PN_CPP_EXTERN explicit timeout_error(const std::string&); };
+/** Raised if there is an error decoding AMQP data as a C++ value. */
+struct decode_error : public error { PN_CPP_EXTERN explicit decode_error(const std::string&); };
+
+/** Raised if there is an error encoding a C++ value as AMQP data. */
+struct encode_error : public error { PN_CPP_EXTERN explicit encode_error(const std::string&); };
+
}
#endif /*!PROTON_CPP_EXCEPTIONS_H*/
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/1622d0e6/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 52195aa..8bd1f85 100644
--- a/proton-c/bindings/cpp/include/proton/message.hpp
+++ b/proton-c/bindings/cpp/include/proton/message.hpp
@@ -22,9 +22,10 @@
*
*/
-#include "proton/data.hpp"
#include "proton/export.hpp"
#include "proton/message_id.hpp"
+#include "proton/annotation_key.hpp"
+#include "proton/pn_unique_ptr.hpp"
#include "proton/value.hpp"
#include "proton/duration.hpp"
@@ -38,22 +39,28 @@ namespace proton {
class link;
class delivery;
class message_id;
+class annotation_key;
/** An AMQP message. Value semantics, can be copied or assigned to make a new message. */
class message
{
public:
+ typedef std::map<std::string, scalar> property_map;
+ typedef std::map<annotation_key, value> annotation_map;
+
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
+ /// Constructor that sets the body from any type that can be assigned to a value.
+ template <class T> explicit message(const T& body_) { body() = body_; }
+
PN_CPP_EXTERN ~message();
+
PN_CPP_EXTERN message& operator=(const message&);
- void swap(message& x);
+ PN_CPP_EXTERN void swap(message& x);
/** Clear the message content and properties. */
PN_CPP_EXTERN void clear();
@@ -99,47 +106,28 @@ class message
///@}
- /** Set the body. */
- PN_CPP_EXTERN void body(const value&);
+ /** Set the body, equivalent to body() = v */
+ template<class T> void body(const T& v) { body() = v; }
- /** Get the body. Note data can be copied to a proton::value */
- PN_CPP_EXTERN const data body() const;
+ /** Get the body. */
+ PN_CPP_EXTERN const value& body() const;
- /** Get a reference to the body data, can be modified in-place. */
- PN_CPP_EXTERN data body();
+ /** Get a reference to the body that can be modified in-place. */
+ PN_CPP_EXTERN value& 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&);
+ /** Application properties map, can be modified in place. */
+ PN_CPP_EXTERN property_map& properties();
+ PN_CPP_EXTERN const property_map& properties() const;
- /** 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;
+ /** Message annotations map, can be modified in place. */
+ PN_CPP_EXTERN annotation_map& annotations();
+ PN_CPP_EXTERN const annotation_map& annotations() const;
- /** Get a reference to the application properties, can be modified in-place.*/
- PN_CPP_EXTERN data properties();
+ /** Delivery instructions map, can be modified in place. */
+ PN_CPP_EXTERN annotation_map& instructions();
+ PN_CPP_EXTERN const annotation_map& instructions() const;
- /** 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);
-
- PN_CPP_EXTERN void annotations(const value&);
- PN_CPP_EXTERN const data annotations() const;
- PN_CPP_EXTERN data annotations();
- PN_CPP_EXTERN void annotation(const proton::amqp_symbol &key, const value &val);
- PN_CPP_EXTERN value annotation(const proton::amqp_symbol &key) const;
- PN_CPP_EXTERN bool erase_annotation(const proton::amqp_symbol &key);
-
- /** Encode into a string, growing the string if necessary. */
+ /** Encode entire message into a string, growing the string if necessary. */
PN_CPP_EXTERN void encode(std::string &bytes) const;
/** Return encoded message as a string */
@@ -148,7 +136,7 @@ class message
/** Decode from string data into the message. */
PN_CPP_EXTERN void decode(const std::string &bytes);
- /// Decode the message from link corresponding to delivery.
+ /** Decode the message corresponding to a delivery from a link. */
PN_CPP_EXTERN void decode(proton::link, proton::delivery);
/**
@@ -160,8 +148,6 @@ class message
* 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.
- *
- * @return the value of the inferred flag for the message
*/
PN_CPP_EXTERN bool inferred() const;
/** Get the inferred flag for a message. */
@@ -247,7 +233,16 @@ class message
PN_CPP_EXTERN void sequence(int32_t);
private:
- pn_message_t *message_;
+ pn_message_t *pn_msg() const;
+ struct impl {
+ PN_CPP_EXTERN impl();
+ PN_CPP_EXTERN ~impl();
+ mutable pn_message_t *msg;
+ mutable value body;
+ } impl_;
+ mutable property_map properties_;
+ mutable annotation_map annotations_;
+ mutable annotation_map instructions_;
};
}
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/1622d0e6/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 4734dff..b08482f 100644
--- a/proton-c/bindings/cpp/include/proton/message_id.hpp
+++ b/proton-c/bindings/cpp/include/proton/message_id.hpp
@@ -20,63 +20,44 @@
*/
#include "proton/types.hpp"
-#include "proton/value.hpp"
+#include "proton/scalar.hpp"
namespace proton {
+class encoder;
+class decoder;
+
/** A message_id can contain one of the following types:
- * uint64_t (aka amqp_ulong), amqp_uuid, amqp_binary or amqp_string.
+ * uint64_t, amqp_uuid, amqp_binary or amqp_string.
*/
-class message_id : public comparable<message_id> {
+class message_id : public restricted_scalar {
public:
- message_id() {}
- message_id(const message_id& x) : value_(x.value_) {}
- 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() { scalar_ = uint64_t(0); }
- message_id& operator=(const message_id& x) { value_ = x.value_; return *this; }
- message_id& operator=(const uint64_t& x) { value_ = x; return *this; }
- message_id& operator=(const amqp_uuid& x) { value_ = x; return *this; }
- message_id& operator=(const amqp_binary& x) { value_ = x; return *this; }
- 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; }
+ ///@name Assign a C++ value, deduce the AMQP type()
+ ///@{
+ message_id& operator=(uint64_t x) { scalar_ = x; return *this; }
+ message_id& operator=(const amqp_uuid& x) { scalar_ = x; return *this; }
+ message_id& operator=(const amqp_binary& x) { scalar_ = x; return *this; }
+ message_id& operator=(const amqp_string& x) { scalar_ = x; return *this; }
+ /// std::string is encoded as amqp_string
+ message_id& operator=(const std::string& x) { scalar_ = amqp_string(x); return *this; }
+ /// char* is encoded as amqp_string
+ message_id& operator=(const char *x) { scalar_ = amqp_string(x); return *this; }
+ ///@}
- void clear() { value_.clear(); }
- bool empty() const { return value_.empty(); }
- type_id type() { return value_.type(); }
+ /// Converting constructor from any type that we can assign from.
+ template <class T> message_id(T x) { *this = x; }
- void get(uint64_t& x) const { value_.get(x); }
- void get(amqp_uuid& x) const { value_.get(x); }
- void get(amqp_binary& x) const { value_.get(x); }
- void get(amqp_string& x) const { value_.get(x); }
- /// Both amqp_binary and amqp_string can be converted to std::string
- void get(std::string& x) const { value_.get(x); }
+ void get(uint64_t& x) const { scalar_.get(x); }
+ void get(amqp_uuid& x) const { scalar_.get(x); }
+ void get(amqp_binary& x) const { scalar_.get(x); }
+ void get(amqp_string& x) const { scalar_.get(x); }
template<class T> T get() const { T x; get(x); return x; }
- // String representation: decimal representation of uint64_t, standard text
- // representation of UUID, amqp_string or amqp_binary are returned without
- // modification.
- std::string& str() const;
-
- bool operator==(const message_id& x) const { return value_ == x.value_; }
- bool operator<(const message_id& x) const { return value_ < x.value_; }
-
- friend std::ostream& operator<<(std::ostream&, const message_id&);
friend PN_CPP_EXTERN encoder operator<<(encoder, const message_id&);
friend PN_CPP_EXTERN decoder operator>>(decoder, message_id&);
-
- private:
- //message_id(const data d) : value_(d) {}
- value value_;
friend class message;
- friend class data;
};
}
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/1622d0e6/proton-c/bindings/cpp/include/proton/scalar.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/scalar.hpp b/proton-c/bindings/cpp/include/proton/scalar.hpp
index 0745281..6fe29fa 100644
--- a/proton-c/bindings/cpp/include/proton/scalar.hpp
+++ b/proton-c/bindings/cpp/include/proton/scalar.hpp
@@ -21,54 +21,56 @@
#include "proton/types.hpp"
#include <iosfwd>
+#include <string>
namespace proton {
-class scalar;
+class encoder;
+class decoder;
-/** scalar holds an instance of an atomic proton type. */
+/** scalar holds an instance of any scalar AMQP type. */
class scalar : public comparable<scalar> {
public:
PN_CPP_EXTERN scalar();
- // Use default assign and copy.
+ PN_CPP_EXTERN scalar(const scalar&);
+ PN_CPP_EXTERN scalar& operator=(const scalar&);
/// Type for the value in the scalar, NULL_TYPE if empty()
PN_CPP_EXTERN type_id type() const;
+
/// True if the scalar is empty.
PN_CPP_EXTERN bool empty() const;
- ///@name Create an scalar, type() is deduced from the C++ type of the value.
+ ///@name Assign a C++ value, deduce the AMQP type()
///@{
- PN_CPP_EXTERN explicit scalar(bool);
- PN_CPP_EXTERN explicit scalar(uint8_t);
- PN_CPP_EXTERN explicit scalar(int8_t);
- PN_CPP_EXTERN explicit scalar(uint16_t);
- PN_CPP_EXTERN explicit scalar(int16_t);
- PN_CPP_EXTERN explicit scalar(uint32_t);
- PN_CPP_EXTERN explicit scalar(int32_t);
- PN_CPP_EXTERN explicit scalar(uint64_t);
- PN_CPP_EXTERN explicit scalar(int64_t);
- PN_CPP_EXTERN explicit scalar(wchar_t);
- PN_CPP_EXTERN explicit scalar(float);
- PN_CPP_EXTERN explicit scalar(double);
- PN_CPP_EXTERN explicit scalar(amqp_timestamp);
- PN_CPP_EXTERN explicit scalar(const amqp_decimal32&);
- PN_CPP_EXTERN explicit scalar(const amqp_decimal64&);
- PN_CPP_EXTERN explicit scalar(const amqp_decimal128&);
- PN_CPP_EXTERN explicit scalar(const amqp_uuid&);
- PN_CPP_EXTERN explicit scalar(const amqp_string&);
- PN_CPP_EXTERN explicit scalar(const amqp_symbol&);
- PN_CPP_EXTERN explicit scalar(const amqp_binary&);
- PN_CPP_EXTERN explicit scalar(const std::string& s); ///< Treated as an AMQP string
- PN_CPP_EXTERN explicit scalar(const char* s); ///< Treated as an AMQP string
+ PN_CPP_EXTERN scalar& operator=(bool);
+ PN_CPP_EXTERN scalar& operator=(uint8_t);
+ PN_CPP_EXTERN scalar& operator=(int8_t);
+ PN_CPP_EXTERN scalar& operator=(uint16_t);
+ PN_CPP_EXTERN scalar& operator=(int16_t);
+ PN_CPP_EXTERN scalar& operator=(uint32_t);
+ PN_CPP_EXTERN scalar& operator=(int32_t);
+ PN_CPP_EXTERN scalar& operator=(uint64_t);
+ PN_CPP_EXTERN scalar& operator=(int64_t);
+ PN_CPP_EXTERN scalar& operator=(wchar_t);
+ PN_CPP_EXTERN scalar& operator=(float);
+ PN_CPP_EXTERN scalar& operator=(double);
+ PN_CPP_EXTERN scalar& operator=(amqp_timestamp);
+ PN_CPP_EXTERN scalar& operator=(const amqp_decimal32&);
+ PN_CPP_EXTERN scalar& operator=(const amqp_decimal64&);
+ PN_CPP_EXTERN scalar& operator=(const amqp_decimal128&);
+ PN_CPP_EXTERN scalar& operator=(const amqp_uuid&);
+ PN_CPP_EXTERN scalar& operator=(const amqp_string&);
+ PN_CPP_EXTERN scalar& operator=(const amqp_symbol&);
+ PN_CPP_EXTERN scalar& operator=(const amqp_binary&);
+ PN_CPP_EXTERN scalar& operator=(const std::string& s); ///< Treated as an AMQP string
+ PN_CPP_EXTERN scalar& operator=(const char* s); ///< Treated as an AMQP string
///@}
- /// Assign to an scalar using the same rules as construction.
- template <class T> scalar& operator=(T x) { return *this = scalar(x); }
+ /// Construct from any type that we can assign from.
+ template <class T> explicit scalar(T x) { *this = x; }
- ///@name get(T&) extracts the value if the types match exactly,
- ///i.e. if `type() == type_id_of<T>::value`
- /// throws type_mismatch otherwise.
+ ///@name get(T&) extracts the value if the types match exactly, throws type_error otherwise.
///@{
PN_CPP_EXTERN void get(bool&) const;
PN_CPP_EXTERN void get(uint8_t&) const;
@@ -97,25 +99,58 @@ class scalar : public comparable<scalar> {
template<class T> T get() const { T x; get(x); return x; }
///@name as_ methods do "loose" conversion, they will convert the scalar's
- ///value to the requested type if possible, else throw type_mismatch
+ ///value to the requested type if possible, else throw type_error
///@{
- PN_CPP_EXTERN int64_t as_int() const; ///< Allowed if type_id_integral(type())
- PN_CPP_EXTERN uint64_t as_uint() const; ///< Allowed if type_id_integral(type())
- PN_CPP_EXTERN double as_double() const; ///< Allowed if type_id_floating_point(type())
- PN_CPP_EXTERN std::string as_string() const; ///< Allowed if type_id_string_like(type())
+ PN_CPP_EXTERN int64_t as_int() const; ///< Allowed if type_id_is_integral(type())
+ PN_CPP_EXTERN uint64_t as_uint() const; ///< Allowed if type_id_is_integral(type())
+ PN_CPP_EXTERN double as_double() const; ///< Allowed if type_id_is_floating_point(type())
+ PN_CPP_EXTERN std::string as_string() const; ///< Allowed if type_id_is_string_like(type())
///@}
- PN_CPP_EXTERN bool operator==(const scalar& x) const;
- /// Note if the values are of different type(), operator< will compare the type()
- PN_CPP_EXTERN bool operator<(const scalar& x) const;
+ friend PN_CPP_EXTERN std::ostream& operator<<(std::ostream&, const scalar&);
+ friend PN_CPP_EXTERN encoder operator<<(encoder, const scalar&);
+ friend PN_CPP_EXTERN decoder operator>>(decoder, scalar&);
+
- PN_CPP_EXTERN friend std::ostream& operator<<(std::ostream&, const scalar&);
+ /// Scalars with different type() are considered unequal even if the values
+ /// are equal as numbers or strings.
+ friend PN_CPP_EXTERN bool operator==(const scalar& x, const scalar& y);
+
+ /// For scalars of different type(), operator< sorts by order of type().
+ friend PN_CPP_EXTERN bool operator<(const scalar& x, const scalar& y);
private:
void ok(pn_type_t) const;
- void set(const std::string&);
+ void set(const std::string&, pn_type_t);
+ void set(const pn_atom_t&);
pn_atom_t atom_;
std::string str_; // Owner of string-like data.
+
+ friend class message;
+};
+
+///@internal base for restricted scalar types
+class restricted_scalar : public comparable<restricted_scalar> {
+ public:
+ operator scalar() const { return scalar_; }
+ type_id type() const { return scalar_.type(); }
+
+ ///@name as_ methods do "loose" conversion, they will convert the scalar's
+ ///value to the requested type if possible, else throw type_error
+ ///@{
+ int64_t as_int() const { return scalar_.as_int(); }
+ uint64_t as_uint() const { return scalar_.as_uint(); }
+ double as_double() const { return scalar_.as_double(); }
+ std::string as_string() const { return scalar_.as_string(); }
+ ///@}
+
+ friend std::ostream& operator<<(std::ostream& o, const restricted_scalar& x) { return o << x.scalar_; }
+ friend bool operator<(const restricted_scalar& x, const restricted_scalar& y) { return x.scalar_ < y.scalar_; }
+ friend bool operator==(const restricted_scalar& x, const restricted_scalar& y) { return x.scalar_ == y.scalar_; }
+
+ protected:
+ restricted_scalar() {}
+ scalar scalar_;
};
}
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/1622d0e6/proton-c/bindings/cpp/include/proton/ssl.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/ssl.hpp b/proton-c/bindings/cpp/include/proton/ssl.hpp
index b3757dc..0518dc6 100644
--- a/proton-c/bindings/cpp/include/proton/ssl.hpp
+++ b/proton-c/bindings/cpp/include/proton/ssl.hpp
@@ -79,7 +79,7 @@ class ssl_domain {
public:
PN_CPP_EXTERN ssl_domain(const ssl_domain&);
PN_CPP_EXTERN ssl_domain& operator=(const ssl_domain&);
- ~ssl_domain();
+ PN_CPP_EXTERN ~ssl_domain();
protected:
ssl_domain(bool is_server);
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/1622d0e6/proton-c/bindings/cpp/include/proton/type_traits.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/type_traits.hpp b/proton-c/bindings/cpp/include/proton/type_traits.hpp
index 494f7db..8f502a3 100644
--- a/proton-c/bindings/cpp/include/proton/type_traits.hpp
+++ b/proton-c/bindings/cpp/include/proton/type_traits.hpp
@@ -76,7 +76,7 @@ template <class T> struct is_same<T,T> { static const bool value=true; };
template< class T > struct remove_const { typedef T type; };
template< class T > struct remove_const<const T> { typedef T type; };
-// Metafunction returning AMQP type for atomic C++ types
+// Metafunction returning AMQP type for scalar C++ types
template <class T, class Enable=void> struct type_id_of;
template<> struct type_id_of<amqp_null> { static const type_id value=NULL_TYPE; };
template<> struct type_id_of<amqp_boolean> { static const type_id value=BOOLEAN; };
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/1622d0e6/proton-c/bindings/cpp/include/proton/types.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/types.hpp b/proton-c/bindings/cpp/include/proton/types.hpp
index 645d9da..db5989b 100644
--- a/proton-c/bindings/cpp/include/proton/types.hpp
+++ b/proton-c/bindings/cpp/include/proton/types.hpp
@@ -67,12 +67,26 @@ enum type_id {
MAP=PN_MAP ///< A sequence of key:value pairs, may be of mixed types.
};
+/// Name of the AMQP type
+PN_CPP_EXTERN std::string type_name(type_id);
+
+/// Print the type_name
+PN_CPP_EXTERN std::ostream& operator<<(std::ostream&, type_id);
+
/// Raised when there is a type mismatch, with the expected and actual type ID.
-struct type_mismatch : public error {
- PN_CPP_EXTERN explicit type_mismatch(type_id want, type_id got, const std::string& =std::string());
+struct type_error : public decode_error {
+ PN_CPP_EXTERN explicit type_error(type_id want, type_id got, const std::string& =std::string());
type_id want; ///< Expected type_id
type_id got; ///< Actual type_id
};
+
+
+///@cond INTERNAL
+/// Provide a full set of comparison operators for proton:: types that have < and ==.
+template <class T> bool operator>(const T &a, const T &b) { return b < a; }
+template <class T> bool operator<=(const T &a, const T &b) { return !(a > b); }
+template <class T> bool operator>=(const T &a, const T &b) { return !(a < b); }
+template <class T> bool operator!=(const T &a, const T &b) { return !(a == b); }
PN_CPP_EXTERN pn_bytes_t pn_bytes(const std::string&);
PN_CPP_EXTERN std::string str(const pn_bytes_t& b);
@@ -107,26 +121,23 @@ typedef double amqp_double;
/// AMQP UTF-8 encoded string.
struct amqp_string : public std::string {
- amqp_string(const std::string& s=std::string()) : std::string(s) {}
- amqp_string(const char* s) : std::string(s) {}
- amqp_string(const pn_bytes_t& b) : std::string(b.start, b.size) {}
- operator pn_bytes_t() const { return pn_bytes(*this); }
+ explicit amqp_string(const std::string& s=std::string()) : std::string(s) {}
+ explicit amqp_string(const char* s) : std::string(s) {}
+ explicit amqp_string(const pn_bytes_t& b) : std::string(b.start, b.size) {}
};
/// AMQP ASCII encoded symbolic name.
struct amqp_symbol : public std::string {
- amqp_symbol(const std::string& s=std::string()) : std::string(s) {}
- amqp_symbol(const char* s) : std::string(s) {}
- amqp_symbol(const pn_bytes_t& b) : std::string(b.start, b.size) {}
- operator pn_bytes_t() const { return pn_bytes(*this); }
+ explicit amqp_symbol(const std::string& s=std::string()) : std::string(s) {}
+ explicit amqp_symbol(const char* s) : std::string(s) {}
+ explicit amqp_symbol(const pn_bytes_t& b) : std::string(b.start, b.size) {}
};
/// AMQP variable-length binary data.
struct amqp_binary : public std::string {
- amqp_binary(const std::string& s=std::string()) : std::string(s) {}
- amqp_binary(const char* s) : std::string(s) {}
- amqp_binary(const pn_bytes_t& b) : std::string(b.start, b.size) {}
- operator pn_bytes_t() const { return pn_bytes(*this); }
+ explicit amqp_binary(const std::string& s=std::string()) : std::string(s) {}
+ explicit amqp_binary(const char* s) : std::string(s) {}
+ explicit amqp_binary(const pn_bytes_t& b) : std::string(b.start, b.size) {}
};
/// Template for opaque proton proton types that can be treated as byte arrays.
@@ -170,40 +181,28 @@ struct amqp_timestamp : public comparable<amqp_timestamp> {
};
PN_CPP_EXTERN std::ostream& operator<<(std::ostream&, const amqp_timestamp&);
-///@cond INTERNAL
-template<class T, type_id A> struct cref {
- typedef T cpp_type;
- static const type_id type;
-
- cref(const T& v) : value(v) {}
- const T& value;
-};
-template <class T, type_id A> const type_id cref<T, A>::type = A;
-///@endcond INTERNAL
-
-/**
- * Indicate the desired AMQP type to use when encoding T.
- * For example to encode a vector as a list:
- *
- * std::vector<amqp_int> v;
- * encoder << as<LIST>(v);
- */
-template <type_id A, class T> cref<T, A> as(const T& value) { return cref<T, A>(value); }
-
// TODO aconway 2015-06-16: described types.
-/// Name of the AMQP type
-PN_CPP_EXTERN std::string type_name(type_id);
-
///@name Attributes of a type_id value, returns same result as the
/// corresponding std::type_traits tests for the corresponding C++ types.
///@{
+/// Any scalar type
PN_CPP_EXTERN bool type_id_is_scalar(type_id);
+/// One of the signed integer types: BYTE, SHORT, INT or LONG
+PN_CPP_EXTERN bool type_id_is_signed_int(type_id);
+/// One of the unsigned integer types: UBYTE, USHORT, UINT or ULONG
+PN_CPP_EXTERN bool type_id_is_unsigned_int(type_id);
+/// Any of the signed or unsigned integers, BOOL, CHAR or TIMESTAMP.
PN_CPP_EXTERN bool type_id_is_integral(type_id);
-PN_CPP_EXTERN bool type_id_is_signed(type_id); ///< CHAR and BOOL are not signed.
+/// A floating point type, float or double
PN_CPP_EXTERN bool type_id_is_floating_point(type_id);
+/// Any signed integer, float or double. BOOL, CHAR and TIMESTAMP are not signed.
+PN_CPP_EXTERN bool type_id_is_signed(type_id);
+/// Any DECIMAL type.
PN_CPP_EXTERN bool type_id_is_decimal(type_id);
-PN_CPP_EXTERN bool type_id_is_string_like(type_id); ///< STRING, SYMBOL, BINARY
+/// STRING, SYMBOL or BINARY
+PN_CPP_EXTERN bool type_id_is_string_like(type_id);
+/// Container types: MAP, LIST, ARRAY or DESCRIBED.
PN_CPP_EXTERN bool type_id_is_container(type_id);
///@}
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/1622d0e6/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 c33eea1..dedcadd 100644
--- a/proton-c/bindings/cpp/include/proton/value.hpp
+++ b/proton-c/bindings/cpp/include/proton/value.hpp
@@ -43,9 +43,10 @@ class decoder;
class value : public comparable<value> {
public:
PN_CPP_EXTERN value();
- PN_CPP_EXTERN value(const value& x);
- // TODO: Should enumerate specifically all the pointer types that can convert to value
- // to avoid accidental conversions to bool this will require enable_if<> or the like
+ PN_CPP_EXTERN value(const value&);
+#if PN_HAS_CPP11
+ PN_CPP_EXTERN value(value&&);
+#endif
template <class T> value(const T& x) : data_(data::create()) { data_.copy(x); }
PN_CPP_EXTERN value& operator=(const value& x);
@@ -65,18 +66,27 @@ class value : public comparable<value> {
/** Get the value. */
template<class T> void get(T &t) const { decoder() >> t; }
+ template<class T> void get(map_ref<T> t) const { decoder() >> t; }
+ template<class T> void get(pairs_ref<T> t) const { decoder() >> t; }
+ template<class T> void get(sequence_ref<T> t) const { decoder() >> t; }
/** Get the value. */
template<class T> T get() const { T t; get(t); return t; }
+ // FIXME aconway 2015-12-28: friend ops.
PN_CPP_EXTERN bool operator==(const value& x) const;
PN_CPP_EXTERN bool operator<(const value& x) const;
+ PN_CPP_EXTERN void swap(value& v);
+
friend PN_CPP_EXTERN class encoder operator<<(class encoder e, const value& dv);
friend PN_CPP_EXTERN class decoder operator>>(class decoder d, value& dv);
friend PN_CPP_EXTERN std::ostream& operator<<(std::ostream& o, const value& dv);
private:
+ value(data d);
+ value& ref(data d);
+
data data_;
friend class message;
};
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/1622d0e6/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 20d0461..4639683 100644
--- a/proton-c/bindings/cpp/src/decoder.cpp
+++ b/proton-c/bindings/cpp/src/decoder.cpp
@@ -21,6 +21,7 @@
#include "proton/decoder.hpp"
#include "proton/value.hpp"
#include "proton/message_id.hpp"
+#include "proton/annotation_key.hpp"
#include "proton_bits.hpp"
#include "msg.hpp"
@@ -34,8 +35,6 @@ namespace proton {
* to be returned by the decoder.
*
*/
-decode_error::decode_error(const std::string& msg) : error("decode: "+msg) {}
-
namespace {
struct save_state {
pn_data_t* data;
@@ -87,8 +86,7 @@ data decoder::data() { return proton::data(pn_object()); }
namespace {
void bad_type(type_id want, type_id got) {
- if (want != got)
- throw decode_error("expected "+type_name(want)+" found "+type_name(got));
+ if (want != got) throw type_error(want, got);
}
type_id pre_get(pn_data_t* data) {
@@ -99,10 +97,10 @@ type_id pre_get(pn_data_t* data) {
}
// Simple extract with no type conversion.
-template <class T, class U> void extract(pn_data_t* data, T& value, U (*get)(pn_data_t*)) {
+template <class T, class U> void extract(pn_data_t* data, T& x, U (*get)(pn_data_t*)) {
save_state ss(data);
bad_type(type_id_of<T>::value, pre_get(data));
- value = T(get(data));
+ x = T(get(data));
ss.cancel(); // No error, no rewind
}
@@ -165,191 +163,211 @@ decoder operator>>(decoder d, value& v) {
return d;
}
-decoder operator>>(decoder d, message_id& id) {
+decoder operator>>(decoder d, message_id& x) {
switch (d.type()) {
case ULONG:
case UUID:
case BINARY:
case STRING:
- return d >> id.value_;
+ return d >> x.scalar_;
default:
throw decode_error("expected one of ulong, uuid, binary or string but found " +
type_name(d.type()));
};
}
+decoder operator>>(decoder d, annotation_key& x) {
+ switch (d.type()) {
+ case ULONG:
+ case SYMBOL:
+ return d >> x.scalar_;
+ default:
+ throw decode_error("expected one of ulong or symbol but found " + type_name(d.type()));
+ };
+}
+
decoder operator>>(decoder d, amqp_null) {
save_state ss(d.pn_object());
bad_type(NULL_TYPE, pre_get(d.pn_object()));
return d;
}
-decoder operator>>(decoder d, amqp_boolean& value) {
- extract(d.pn_object(), value, pn_data_get_bool);
+decoder operator>>(decoder d, scalar& x) {
+ save_state ss(d.pn_object());
+ type_id got = pre_get(d.pn_object());
+ if (!type_id_is_scalar(got))
+ throw decode_error("expected scalar, found "+type_name(got));
+ x.set(pn_data_get_atom(d.pn_object()));
+ ss.cancel(); // No error, no rewind
+ return d;
+}
+
+decoder operator>>(decoder d, amqp_boolean &x) {
+ extract(d.pn_object(), x, pn_data_get_bool);
return d;
}
-decoder operator>>(decoder d0, amqp_ubyte& value) {
+decoder operator>>(decoder d0, amqp_ubyte &x) {
pn_data_t* d = d0.pn_object();
save_state ss(d);
switch (pre_get(d)) {
- case UBYTE: value = pn_data_get_ubyte(d); break;
+ case UBYTE: x = pn_data_get_ubyte(d); break;
default: bad_type(UBYTE, type_id(type_id(pn_data_type(d))));
}
ss.cancel();
return d0;
}
-decoder operator>>(decoder d0, amqp_byte& value) {
+decoder operator>>(decoder d0, amqp_byte &x) {
pn_data_t* d = d0.pn_object();
save_state ss(d);
switch (pre_get(d)) {
- case BYTE: value = pn_data_get_byte(d); break;
+ case BYTE: x = pn_data_get_byte(d); break;
default: bad_type(BYTE, type_id(type_id(pn_data_type(d))));
}
ss.cancel();
return d0;
}
-decoder operator>>(decoder d0, amqp_ushort& value) {
+decoder operator>>(decoder d0, amqp_ushort &x) {
pn_data_t* d = d0.pn_object();
save_state ss(d);
switch (pre_get(d)) {
- case UBYTE: value = pn_data_get_ubyte(d); break;
- case USHORT: value = pn_data_get_ushort(d); break;
+ case UBYTE: x = pn_data_get_ubyte(d); break;
+ case USHORT: x = pn_data_get_ushort(d); break;
default: bad_type(USHORT, type_id(type_id(pn_data_type(d))));
}
ss.cancel();
return d0;
}
-decoder operator>>(decoder d0, amqp_short& value) {
+decoder operator>>(decoder d0, amqp_short &x) {
pn_data_t* d = d0.pn_object();
save_state ss(d);
switch (pre_get(d)) {
- case BYTE: value = pn_data_get_byte(d); break;
- case SHORT: value = pn_data_get_short(d); break;
+ case BYTE: x = pn_data_get_byte(d); break;
+ case SHORT: x = pn_data_get_short(d); break;
default: bad_type(SHORT, type_id(pn_data_type(d)));
}
ss.cancel();
return d0;
}
-decoder operator>>(decoder d0, amqp_uint& value) {
+decoder operator>>(decoder d0, amqp_uint &x) {
pn_data_t* d = d0.pn_object();
save_state ss(d);
switch (pre_get(d)) {
- case UBYTE: value = pn_data_get_ubyte(d); break;
- case USHORT: value = pn_data_get_ushort(d); break;
- case UINT: value = pn_data_get_uint(d); break;
+ case UBYTE: x = pn_data_get_ubyte(d); break;
+ case USHORT: x = pn_data_get_ushort(d); break;
+ case UINT: x = pn_data_get_uint(d); break;
default: bad_type(UINT, type_id(pn_data_type(d)));
}
ss.cancel();
return d0;
}
-decoder operator>>(decoder d0, amqp_int& value) {
+decoder operator>>(decoder d0, amqp_int &x) {
pn_data_t* d = d0.pn_object();
save_state ss(d);
switch (pre_get(d)) {
- case BYTE: value = pn_data_get_byte(d); break;
- case SHORT: value = pn_data_get_short(d); break;
- case INT: value = pn_data_get_int(d); break;
+ case BYTE: x = pn_data_get_byte(d); break;
+ case SHORT: x = pn_data_get_short(d); break;
+ case INT: x = pn_data_get_int(d); break;
default: bad_type(INT, type_id(pn_data_type(d)));
}
ss.cancel();
return d0;
}
-decoder operator>>(decoder d0, amqp_ulong& value) {
+decoder operator>>(decoder d0, amqp_ulong &x) {
pn_data_t* d = d0.pn_object();
save_state ss(d);
switch (pre_get(d)) {
- case UBYTE: value = pn_data_get_ubyte(d); break;
- case USHORT: value = pn_data_get_ushort(d); break;
- case UINT: value = pn_data_get_uint(d); break;
- case ULONG: value = pn_data_get_ulong(d); break;
+ case UBYTE: x = pn_data_get_ubyte(d); break;
+ case USHORT: x = pn_data_get_ushort(d); break;
+ case UINT: x = pn_data_get_uint(d); break;
+ case ULONG: x = pn_data_get_ulong(d); break;
default: bad_type(ULONG, type_id(pn_data_type(d)));
}
ss.cancel();
return d0;
}
-decoder operator>>(decoder d0, amqp_long& value) {
+decoder operator>>(decoder d0, amqp_long &x) {
pn_data_t* d = d0.pn_object();
save_state ss(d);
switch (pre_get(d)) {
- case BYTE: value = pn_data_get_byte(d); break;
- case SHORT: value = pn_data_get_short(d); break;
- case INT: value = pn_data_get_int(d); break;
- case LONG: value = pn_data_get_long(d); break;
+ case BYTE: x = pn_data_get_byte(d); break;
+ case SHORT: x = pn_data_get_short(d); break;
+ case INT: x = pn_data_get_int(d); break;
+ case LONG: x = pn_data_get_long(d); break;
default: bad_type(LONG, type_id(pn_data_type(d)));
}
ss.cancel();
return d0;
}
-decoder operator>>(decoder d, amqp_char& value) {
- extract(d.pn_object(), value, pn_data_get_char);
+decoder operator>>(decoder d, amqp_char &x) {
+ extract(d.pn_object(), x, pn_data_get_char);
return d;
}
-decoder operator>>(decoder d, amqp_timestamp& value) {
- extract(d.pn_object(), value, pn_data_get_timestamp);
+decoder operator>>(decoder d, amqp_timestamp &x) {
+ extract(d.pn_object(), x, pn_data_get_timestamp);
return d;
}
-decoder operator>>(decoder d0, amqp_float& value) {
+decoder operator>>(decoder d0, amqp_float &x) {
pn_data_t* d = d0.pn_object();
save_state ss(d);
switch (pre_get(d)) {
- case FLOAT: value = pn_data_get_float(d); break;
- case DOUBLE: value = float(pn_data_get_double(d)); break;
+ case FLOAT: x = pn_data_get_float(d); break;
+ case DOUBLE: x = float(pn_data_get_double(d)); break;
default: bad_type(FLOAT, type_id(pn_data_type(d)));
}
ss.cancel();
return d0;
}
-decoder operator>>(decoder d0, amqp_double& value) {
+decoder operator>>(decoder d0, amqp_double &x) {
pn_data_t* d = d0.pn_object();
save_state ss(d);
switch (pre_get(d)) {
- case FLOAT: value = pn_data_get_float(d); break;
- case DOUBLE: value = pn_data_get_double(d); break;
+ case FLOAT: x = pn_data_get_float(d); break;
+ case DOUBLE: x = pn_data_get_double(d); break;
default: bad_type(DOUBLE, type_id(pn_data_type(d)));
}
ss.cancel();
return d0;
}
-decoder operator>>(decoder d, amqp_decimal32& value) {
- extract(d.pn_object(), value, pn_data_get_decimal32);
+decoder operator>>(decoder d, amqp_decimal32 &x) {
+ extract(d.pn_object(), x, pn_data_get_decimal32);
return d;
}
-decoder operator>>(decoder d, amqp_decimal64& value) {
- extract(d.pn_object(), value, pn_data_get_decimal64);
+decoder operator>>(decoder d, amqp_decimal64 &x) {
+ extract(d.pn_object(), x, pn_data_get_decimal64);
return d;
}
-decoder operator>>(decoder d, amqp_decimal128& value) {
- extract(d.pn_object(), value, pn_data_get_decimal128);
+decoder operator>>(decoder d, amqp_decimal128 &x) {
+ extract(d.pn_object(), x, pn_data_get_decimal128);
return d;
}
-decoder operator>>(decoder d, amqp_uuid& value) {
- extract(d.pn_object(), value, pn_data_get_uuid);
+decoder operator>>(decoder d, amqp_uuid &x) {
+ extract(d.pn_object(), x, pn_data_get_uuid);
return d;
}
-decoder operator>>(decoder d0, std::string& value) {
+decoder operator>>(decoder d0, std::string &x) {
pn_data_t* d = d0.pn_object();
save_state ss(d);
switch (pre_get(d)) {
- case STRING: value = str(pn_data_get_string(d)); break;
- case BINARY: value = str(pn_data_get_binary(d)); break;
- case SYMBOL: value = str(pn_data_get_symbol(d)); break;
+ case STRING: x = str(pn_data_get_string(d)); break;
+ case BINARY: x = str(pn_data_get_binary(d)); break;
+ case SYMBOL: x = str(pn_data_get_symbol(d)); break;
default: bad_type(STRING, type_id(pn_data_type(d)));
}
ss.cancel();
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/1622d0e6/proton-c/bindings/cpp/src/encode_decode_test.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/encode_decode_test.cpp b/proton-c/bindings/cpp/src/encode_decode_test.cpp
index 3e15a58..8c285ac 100644
--- a/proton-c/bindings/cpp/src/encode_decode_test.cpp
+++ b/proton-c/bindings/cpp/src/encode_decode_test.cpp
@@ -48,31 +48,13 @@ template <class T> void value_test(T x, type_id tid, const std::string& s, T y)
ASSERT(y > x);
}
-void value_tests() {
- value_test(false, BOOLEAN, "false", true);
- value_test(amqp_ubyte(42), UBYTE, "42", amqp_ubyte(50));
- value_test(amqp_byte(-42), BYTE, "-42", amqp_byte(-40));
- value_test(amqp_ushort(4242), USHORT, "4242", amqp_ushort(5252));
- value_test(amqp_short(-4242), SHORT, "-4242", amqp_short(3));
- value_test(amqp_uint(4242), UINT, "4242", amqp_uint(5252));
- value_test(amqp_int(-4242), INT, "-4242", amqp_int(3));
- value_test(amqp_ulong(4242), ULONG, "4242", amqp_ulong(5252));
- value_test(amqp_long(-4242), LONG, "-4242", amqp_long(3));
- value_test(amqp_float(1.234), FLOAT, "1.234", amqp_float(2.345));
- value_test(amqp_double(11.2233), DOUBLE, "11.2233", amqp_double(12));
- value_test(amqp_string("aaa"), STRING, "aaa", amqp_string("aaaa"));
- value_test(std::string("xxx"), STRING, "xxx", std::string("yyy"));
- value_test(amqp_symbol("aaa"), SYMBOL, "aaa", amqp_symbol("aaaa"));
- value_test(amqp_binary("aaa"), BINARY, "b\"aaa\"", amqp_binary("aaaa"));
-}
-
// Map values
void map_test() {
std::map<string, int> m;
m["a"] = 1;
m["b"] = 2;
m["c"] = 3;
- proton::value v = m;
+ value v = m;
ASSERT_EQUAL("{\"a\"=1, \"b\"=2, \"c\"=3}", str(v));
std::map<value, value> mv;
v.get(mv);
@@ -81,8 +63,9 @@ void map_test() {
mv.erase("c");
v = value(mv);
ASSERT_EQUAL("{\"a\"=1, \"b\"=b\"xyz\"}", str(v));
+
std::vector<std::pair<string, value> > vec;
- v.decoder() >> to_pairs(vec); // FIXME aconway 2015-11-17: get doesn't work with pairs.
+ v.get(to_pairs(vec));
ASSERT_EQUAL(2, vec.size());
ASSERT_EQUAL(std::make_pair(std::string("a"), value(1)), vec[0]);
ASSERT_EQUAL(std::make_pair(std::string("b"), value(amqp_binary("xyz"))), vec[1]);
@@ -90,7 +73,21 @@ void map_test() {
int main(int, char**) {
int failed = 0;
+ RUN_TEST(failed, value_test(false, BOOLEAN, "false", true));
+ RUN_TEST(failed, value_test(amqp_ubyte(42), UBYTE, "42", amqp_ubyte(50)));
+ RUN_TEST(failed, value_test(amqp_byte(-42), BYTE, "-42", amqp_byte(-40)));
+ RUN_TEST(failed, value_test(amqp_ushort(4242), USHORT, "4242", amqp_ushort(5252)));
+ RUN_TEST(failed, value_test(amqp_short(-4242), SHORT, "-4242", amqp_short(3)));
+ RUN_TEST(failed, value_test(amqp_uint(4242), UINT, "4242", amqp_uint(5252)));
+ RUN_TEST(failed, value_test(amqp_int(-4242), INT, "-4242", amqp_int(3)));
+ RUN_TEST(failed, value_test(amqp_ulong(4242), ULONG, "4242", amqp_ulong(5252)));
+ RUN_TEST(failed, value_test(amqp_long(-4242), LONG, "-4242", amqp_long(3)));
+ RUN_TEST(failed, value_test(amqp_float(1.234), FLOAT, "1.234", amqp_float(2.345)));
+ RUN_TEST(failed, value_test(amqp_double(11.2233), DOUBLE, "11.2233", amqp_double(12)));
+ RUN_TEST(failed, value_test(amqp_string("aaa"), STRING, "aaa", amqp_string("aaaa")));
+ RUN_TEST(failed, value_test(std::string("xxx"), STRING, "xxx", std::string("yyy")));
+ RUN_TEST(failed, value_test(amqp_symbol("aaa"), SYMBOL, "aaa", amqp_symbol("aaaa")));
+ RUN_TEST(failed, value_test(amqp_binary("aaa"), BINARY, "b\"aaa\"", amqp_binary("aaaa")));
RUN_TEST(failed, map_test());
- RUN_TEST(failed, value_tests());
return failed;
}
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/1622d0e6/proton-c/bindings/cpp/src/encoder.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/encoder.cpp b/proton-c/bindings/cpp/src/encoder.cpp
index 327426a..109b290 100644
--- a/proton-c/bindings/cpp/src/encoder.cpp
+++ b/proton-c/bindings/cpp/src/encoder.cpp
@@ -20,6 +20,7 @@
#include "proton/data.hpp"
#include "proton/encoder.hpp"
#include "proton/message_id.hpp"
+#include "proton/annotation_key.hpp"
#include "proton/value.hpp"
#include "proton_bits.hpp"
@@ -100,35 +101,39 @@ encoder operator<<(encoder e, finish) {
namespace {
template <class T, class U>
-encoder insert(encoder e, pn_data_t* data, T& value, int (*put)(pn_data_t*, U)) {
+encoder insert(encoder e, pn_data_t* data, T& x, int (*put)(pn_data_t*, U)) {
save_state ss(data); // Save state in case of error.
- check(put(data, value), data);
+ check(put(data, x), data);
ss.cancel(); // Don't restore state, all is good.
return e;
}
+
+int pn_data_put_amqp_string(pn_data_t *d, const amqp_string& x) { return pn_data_put_string(d, pn_bytes(x)); }
+int pn_data_put_amqp_binary(pn_data_t *d, const amqp_binary& x) { return pn_data_put_binary(d, pn_bytes(x)); }
+int pn_data_put_amqp_symbol(pn_data_t *d, const amqp_symbol& x) { return pn_data_put_symbol(d, pn_bytes(x)); }
}
encoder operator<<(encoder e, amqp_null) { pn_data_put_null(e.pn_object()); return e; }
-encoder operator<<(encoder e, amqp_boolean value) { return insert(e, e.pn_object(), value, pn_data_put_bool); }
-encoder operator<<(encoder e, amqp_ubyte value) { return insert(e, e.pn_object(), value, pn_data_put_ubyte); }
-encoder operator<<(encoder e, amqp_byte value) { return insert(e, e.pn_object(), value, pn_data_put_byte); }
-encoder operator<<(encoder e, amqp_ushort value) { return insert(e, e.pn_object(), value, pn_data_put_ushort); }
-encoder operator<<(encoder e, amqp_short value) { return insert(e, e.pn_object(), value, pn_data_put_short); }
-encoder operator<<(encoder e, amqp_uint value) { return insert(e, e.pn_object(), value, pn_data_put_uint); }
-encoder operator<<(encoder e, amqp_int value) { return insert(e, e.pn_object(), value, pn_data_put_int); }
-encoder operator<<(encoder e, amqp_char value) { return insert(e, e.pn_object(), value, pn_data_put_char); }
-encoder operator<<(encoder e, amqp_ulong value) { return insert(e, e.pn_object(), value, pn_data_put_ulong); }
-encoder operator<<(encoder e, amqp_long value) { return insert(e, e.pn_object(), value, pn_data_put_long); }
-encoder operator<<(encoder e, amqp_timestamp value) { return insert(e, e.pn_object(), value, pn_data_put_timestamp); }
-encoder operator<<(encoder e, amqp_float value) { return insert(e, e.pn_object(), value, pn_data_put_float); }
-encoder operator<<(encoder e, amqp_double value) { return insert(e, e.pn_object(), value, pn_data_put_double); }
-encoder operator<<(encoder e, amqp_decimal32 value) { return insert(e, e.pn_object(), value, pn_data_put_decimal32); }
-encoder operator<<(encoder e, amqp_decimal64 value) { return insert(e, e.pn_object(), value, pn_data_put_decimal64); }
-encoder operator<<(encoder e, amqp_decimal128 value) { return insert(e, e.pn_object(), value, pn_data_put_decimal128); }
-encoder operator<<(encoder e, amqp_uuid value) { return insert(e, e.pn_object(), value, pn_data_put_uuid); }
-encoder operator<<(encoder e, amqp_string value) { return insert(e, e.pn_object(), value, pn_data_put_string); }
-encoder operator<<(encoder e, amqp_symbol value) { return insert(e, e.pn_object(), value, pn_data_put_symbol); }
-encoder operator<<(encoder e, amqp_binary value) { return insert(e, e.pn_object(), value, pn_data_put_binary); }
+encoder operator<<(encoder e, amqp_boolean x) { return insert(e, e.pn_object(), x, pn_data_put_bool); }
+encoder operator<<(encoder e, amqp_ubyte x) { return insert(e, e.pn_object(), x, pn_data_put_ubyte); }
+encoder operator<<(encoder e, amqp_byte x) { return insert(e, e.pn_object(), x, pn_data_put_byte); }
+encoder operator<<(encoder e, amqp_ushort x) { return insert(e, e.pn_object(), x, pn_data_put_ushort); }
+encoder operator<<(encoder e, amqp_short x) { return insert(e, e.pn_object(), x, pn_data_put_short); }
+encoder operator<<(encoder e, amqp_uint x) { return insert(e, e.pn_object(), x, pn_data_put_uint); }
+encoder operator<<(encoder e, amqp_int x) { return insert(e, e.pn_object(), x, pn_data_put_int); }
+encoder operator<<(encoder e, amqp_char x) { return insert(e, e.pn_object(), x, pn_data_put_char); }
+encoder operator<<(encoder e, amqp_ulong x) { return insert(e, e.pn_object(), x, pn_data_put_ulong); }
+encoder operator<<(encoder e, amqp_long x) { return insert(e, e.pn_object(), x, pn_data_put_long); }
+encoder operator<<(encoder e, amqp_timestamp x) { return insert(e, e.pn_object(), x, pn_data_put_timestamp); }
+encoder operator<<(encoder e, amqp_float x) { return insert(e, e.pn_object(), x, pn_data_put_float); }
+encoder operator<<(encoder e, amqp_double x) { return insert(e, e.pn_object(), x, pn_data_put_double); }
+encoder operator<<(encoder e, amqp_decimal32 x) { return insert(e, e.pn_object(), x, pn_data_put_decimal32); }
+encoder operator<<(encoder e, amqp_decimal64 x) { return insert(e, e.pn_object(), x, pn_data_put_decimal64); }
+encoder operator<<(encoder e, amqp_decimal128 x) { return insert(e, e.pn_object(), x, pn_data_put_decimal128); }
+encoder operator<<(encoder e, amqp_uuid x) { return insert(e, e.pn_object(), x, pn_data_put_uuid); }
+encoder operator<<(encoder e, amqp_string x) { return insert(e, e.pn_object(), x, pn_data_put_amqp_string); }
+encoder operator<<(encoder e, amqp_symbol x) { return insert(e, e.pn_object(), x, pn_data_put_amqp_symbol); }
+encoder operator<<(encoder e, amqp_binary x) { return insert(e, e.pn_object(), x, pn_data_put_amqp_binary); }
encoder operator<<(encoder e, const value& v) {
data edata = e.data();
@@ -138,6 +143,11 @@ encoder operator<<(encoder e, const value& v) {
return e;
}
-encoder operator<<(encoder e, const message_id& v) { return e << v.value_; }
+encoder operator<<(encoder e, const scalar& x) {
+ return insert(e, e.pn_object(), x.atom_, pn_data_put_atom);
+}
+
+encoder operator<<(encoder e, const message_id& x) { return e << x.scalar_; }
+encoder operator<<(encoder e, const annotation_key& x) { return e << x.scalar_; }
}
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/1622d0e6/proton-c/bindings/cpp/src/error.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/error.cpp b/proton-c/bindings/cpp/src/error.cpp
index 980d6c0..8382a70 100644
--- a/proton-c/bindings/cpp/src/error.cpp
+++ b/proton-c/bindings/cpp/src/error.cpp
@@ -27,4 +27,6 @@ error::error(const std::string& msg) : std::runtime_error(prefix+msg) {}
timeout_error::timeout_error(const std::string& msg) : error(msg) {}
+decode_error::decode_error(const std::string& msg) : error("decode: "+msg) {}
+
}
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/1622d0e6/proton-c/bindings/cpp/src/event.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/event.cpp b/proton-c/bindings/cpp/src/event.cpp
index 2a35ee8..b3e93d8 100644
--- a/proton-c/bindings/cpp/src/event.cpp
+++ b/proton-c/bindings/cpp/src/event.cpp
@@ -77,5 +77,5 @@ class message &event::message() const {
throw error(MSG("No message associated with event"));
}
-event_loop::~event_loop() {} // FIXME aconway 2015-12-28: move
+event_loop::~event_loop() {}
}
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/1622d0e6/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 c2fcd00..c7ee1f6 100644
--- a/proton-c/bindings/cpp/src/message.cpp
+++ b/proton-c/bindings/cpp/src/message.cpp
@@ -19,6 +19,7 @@
*
*/
+#include "proton/data.hpp"
#include "proton/message.hpp"
#include "proton/error.hpp"
#include "proton/link.hpp"
@@ -31,24 +32,39 @@
#include "msg.hpp"
#include "proton_bits.hpp"
-#include <cstring>
+#include <string>
#include <assert.h>
namespace proton {
-message::message() : message_(::pn_message()) {}
+// impl exists so body is pre-constructed in reference mode (prevent it creating its own data)
+// for all message ctors.
+message::impl::impl() : msg(0), body(0) {}
-message::message(const message &m) : message_(::pn_message()) { *this = m; }
+message::impl::~impl() {
+ if (msg) {
+ body.ref(0); // Clear the reference.
+ pn_message_free(msg);
+ }
+}
-#if defined(PN_HAS_CPP11) && PN_HAS_CPP11
-message::message(message &&m) : message_(::pn_message()) { swap(m); }
-#endif
+// Lazy construct the message.
+pn_message_t* message::pn_msg() const {
+ if (!impl_.msg) impl_.msg = pn_message();
+ return impl_.msg;
+}
+
+message::message() {}
+
+message::message(const message &m) { *this = m; }
-message::message(const value& v) : message_(::pn_message()) { body(v); }
+#if PN_HAS_CPP11
+message::message(message &&m) { swap(m); }
+#endif
-message::~message() { ::pn_message_free(message_); }
+message::~message() {}
-void message::swap(message& m) { std::swap(message_, m.message_); }
+void message::swap(message& m) { std::swap(impl_.msg, m.impl_.msg); }
message& message::operator=(const message& m) {
// TODO aconway 2015-08-10: more efficient pn_message_copy function
@@ -58,7 +74,7 @@ message& message::operator=(const message& m) {
return *this;
}
-void message::clear() { pn_message_clear(message_); }
+void message::clear() { if (impl_.msg) pn_message_clear(impl_.msg); }
namespace {
void check(int err) {
@@ -66,7 +82,7 @@ void check(int err) {
}
} // namespace
-void message::id(const message_id& id) { data(pn_message_id(message_)).copy(id.value_); }
+void message::id(const message_id& id) { pn_message_set_id(pn_msg(), id.scalar_.atom_); }
namespace {
inline message_id from_pn_atom(const pn_atom_t& v) {
@@ -86,222 +102,169 @@ inline message_id from_pn_atom(const pn_atom_t& v) {
}
message_id message::id() const {
- return from_pn_atom(pn_message_get_id(message_));
+ return from_pn_atom(pn_message_get_id(pn_msg()));
}
void message::user_id(const std::string &id) {
- check(pn_message_set_user_id(message_, pn_bytes(id)));
+ check(pn_message_set_user_id(pn_msg(), pn_bytes(id)));
}
std::string message::user_id() const {
- return str(pn_message_get_user_id(message_));
+ return str(pn_message_get_user_id(pn_msg()));
}
void message::address(const std::string &addr) {
- check(pn_message_set_address(message_, addr.c_str()));
+ check(pn_message_set_address(pn_msg(), addr.c_str()));
}
std::string message::address() const {
- const char* addr = pn_message_get_address(message_);
+ const char* addr = pn_message_get_address(pn_msg());
return addr ? std::string(addr) : std::string();
}
void message::subject(const std::string &s) {
- check(pn_message_set_subject(message_, s.c_str()));
+ check(pn_message_set_subject(pn_msg(), s.c_str()));
}
std::string message::subject() const {
- const char* s = pn_message_get_subject(message_);
+ const char* s = pn_message_get_subject(pn_msg());
return s ? std::string(s) : std::string();
}
void message::reply_to(const std::string &s) {
- check(pn_message_set_reply_to(message_, s.c_str()));
+ check(pn_message_set_reply_to(pn_msg(), s.c_str()));
}
std::string message::reply_to() const {
- const char* s = pn_message_get_reply_to(message_);
+ const char* s = pn_message_get_reply_to(pn_msg());
return s ? std::string(s) : std::string();
}
void message::correlation_id(const message_id& id) {
- data(pn_message_correlation_id(message_)).copy(id.value_);
+ data(pn_message_correlation_id(pn_msg())).copy(id.scalar_);
}
message_id message::correlation_id() const {
- return from_pn_atom(pn_message_get_correlation_id(message_));
+ return from_pn_atom(pn_message_get_correlation_id(pn_msg()));
}
void message::content_type(const std::string &s) {
- check(pn_message_set_content_type(message_, s.c_str()));
+ check(pn_message_set_content_type(pn_msg(), s.c_str()));
}
std::string message::content_type() const {
- const char* s = pn_message_get_content_type(message_);
+ const char* s = pn_message_get_content_type(pn_msg());
return s ? std::string(s) : std::string();
}
void message::content_encoding(const std::string &s) {
- check(pn_message_set_content_encoding(message_, s.c_str()));
+ check(pn_message_set_content_encoding(pn_msg(), s.c_str()));
}
std::string message::content_encoding() const {
- const char* s = pn_message_get_content_encoding(message_);
+ const char* s = pn_message_get_content_encoding(pn_msg());
return s ? std::string(s) : std::string();
}
void message::expiry_time(amqp_timestamp t) {
- pn_message_set_expiry_time(message_, t.milliseconds);
+ pn_message_set_expiry_time(pn_msg(), t.milliseconds);
}
amqp_timestamp message::expiry_time() const {
- return amqp_timestamp(pn_message_get_expiry_time(message_));
+ return amqp_timestamp(pn_message_get_expiry_time(pn_msg()));
}
void message::creation_time(amqp_timestamp t) {
- pn_message_set_creation_time(message_, t);
+ pn_message_set_creation_time(pn_msg(), t);
}
amqp_timestamp message::creation_time() const {
- return pn_message_get_creation_time(message_);
+ return pn_message_get_creation_time(pn_msg());
}
void message::group_id(const std::string &s) {
- check(pn_message_set_group_id(message_, s.c_str()));
+ check(pn_message_set_group_id(pn_msg(), s.c_str()));
}
std::string message::group_id() const {
- const char* s = pn_message_get_group_id(message_);
+ const char* s = pn_message_get_group_id(pn_msg());
return s ? std::string(s) : std::string();
}
void message::reply_to_group_id(const std::string &s) {
- check(pn_message_set_reply_to_group_id(message_, s.c_str()));
+ check(pn_message_set_reply_to_group_id(pn_msg(), s.c_str()));
}
std::string message::reply_to_group_id() const {
- const char* s = pn_message_get_reply_to_group_id(message_);
+ const char* s = pn_message_get_reply_to_group_id(pn_msg());
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().copy(v); }
+bool message::inferred() const { return pn_message_is_inferred(pn_msg()); }
-const data message::body() const {
- return pn_message_body(message_);
-}
+void message::inferred(bool b) { pn_message_set_inferred(pn_msg(), b); }
-data message::body() {
- return pn_message_body(message_);
-}
+const value& message::body() const { return impl_.body.ref(pn_message_body(pn_msg())); }
+value& message::body() { return impl_.body.ref(pn_message_body(pn_msg())); }
-void message::properties(const value& v) {
- properties().copy(v);
-}
+// MAP CACHING: the properties, annotations and instructions maps can either be
+// encoded in the pn_message pn_data_t structures OR decoded as C++ map members
+// of the message but not both. At least one of the pn_data_t or the map member
+// is always empty, the non-empty one is the authority.
-const data message::properties() const {
- return pn_message_properties(message_);
-}
-
-data message::properties() {
- return 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;
+// Decode a map on demand
+template<class M> M& get_map(pn_message_t* msg, pn_data_t* (*get)(pn_message_t*), M& map) {
+ data d(get(msg));
+ if (map.empty() && !d.empty()) {
+ d.decoder() >> rewind() >> map;
+ d.clear(); // The map member is now the authority.
}
- return value();
+ return map;
}
-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;
- }
+// Encode a map if necessary.
+template<class M> M& put_map(pn_message_t* msg, pn_data_t* (*get)(pn_message_t*), M& map) {
+ data d(get(msg));
+ if (d.empty() && !map.empty()) {
+ d.encoder() << map;
+ map.clear(); // The encoded pn_data_t is now the authority.
}
- return false;
+ return map;
}
-void message::annotations(const value& v) {
- annotations().copy(v);
+message::property_map& message::properties() {
+ return get_map(pn_msg(), pn_message_properties, properties_);
}
-const data message::annotations() const {
- return pn_message_annotations(message_);
+const message::property_map& message::properties() const {
+ return get_map(pn_msg(), pn_message_properties, properties_);
}
-data message::annotations() {
- return pn_message_annotations(message_);
-}
-namespace {
-typedef std::map<proton::amqp_symbol, value> annotation_map;
+message::annotation_map& message::annotations() {
+ return get_map(pn_msg(), pn_message_annotations, annotations_);
}
-void message::annotation(const proton::amqp_symbol &k, const value &v) {
- annotation_map m;
- if (!annotations().empty())
- annotations().get(m);
- m[k] = v;
- annotations(m);
+const message::annotation_map& message::annotations() const {
+ return get_map(pn_msg(), pn_message_annotations, annotations_);
}
-value message::annotation(const proton::amqp_symbol &k) const {
- if (!annotations().empty()) {
- annotation_map m;
- annotations().get(m);
- annotation_map::const_iterator i = m.find(k);
- if (i != m.end())
- return i->second;
- }
- return value();
+message::annotation_map& message::instructions() {
+ return get_map(pn_msg(), pn_message_instructions, instructions_);
}
-bool message::erase_annotation(const proton::amqp_symbol &k) {
- if (!annotations().empty()) {
- annotation_map m;
- annotations().get(m);
- if (m.erase(k)) {
- annotations(m);
- return true;
- }
- }
- return false;
+const message::annotation_map& message::instructions() const {
+ return get_map(pn_msg(), pn_message_instructions, instructions_);
}
void message::encode(std::string &s) const {
+ put_map(pn_msg(), pn_message_properties, properties_);
+ put_map(pn_msg(), pn_message_annotations, annotations_);
+ put_map(pn_msg(), pn_message_instructions, instructions_);
size_t sz = s.capacity();
if (sz < 512) sz = 512;
while (true) {
s.resize(sz);
- int err = pn_message_encode(message_, const_cast<char*>(s.data()), &sz);
+ int err = pn_message_encode(pn_msg(), const_cast<char*>(s.data()), &sz);
if (err) {
if (err != PN_OVERFLOW)
check(err);
@@ -320,7 +283,10 @@ std::string message::encode() const {
}
void message::decode(const std::string &s) {
- check(pn_message_decode(message_, s.data(), s.size()));
+ properties_.clear();
+ annotations_.clear();
+ instructions_.clear();
+ check(pn_message_decode(pn_msg(), s.data(), s.size()));
}
void message::decode(proton::link link, proton::delivery delivery) {
@@ -333,22 +299,22 @@ void message::decode(proton::link link, proton::delivery delivery) {
link.advance();
}
-bool message::durable() const { return pn_message_is_durable(message_); }
-void message::durable(bool b) { pn_message_set_durable(message_, b); }
+bool message::durable() const { return pn_message_is_durable(pn_msg()); }
+void message::durable(bool b) { pn_message_set_durable(pn_msg(), b); }
-duration message::ttl() const { return duration(pn_message_get_ttl(message_)); }
-void message::ttl(duration d) { pn_message_set_ttl(message_, d.milliseconds); }
+duration message::ttl() const { return duration(pn_message_get_ttl(pn_msg())); }
+void message::ttl(duration d) { pn_message_set_ttl(pn_msg(), d.milliseconds); }
-uint8_t message::priority() const { return pn_message_get_priority(message_); }
-void message::priority(uint8_t d) { pn_message_set_priority(message_, d); }
+uint8_t message::priority() const { return pn_message_get_priority(pn_msg()); }
+void message::priority(uint8_t d) { pn_message_set_priority(pn_msg(), d); }
-bool message::first_acquirer() const { return pn_message_is_first_acquirer(message_); }
-void message::first_acquirer(bool b) { pn_message_set_first_acquirer(message_, b); }
+bool message::first_acquirer() const { return pn_message_is_first_acquirer(pn_msg()); }
+void message::first_acquirer(bool b) { pn_message_set_first_acquirer(pn_msg(), b); }
-uint32_t message::delivery_count() const { return pn_message_get_delivery_count(message_); }
-void message::delivery_count(uint32_t d) { pn_message_set_delivery_count(message_, d); }
+uint32_t message::delivery_count() const { return pn_message_get_delivery_count(pn_msg()); }
+void message::delivery_count(uint32_t d) { pn_message_set_delivery_count(pn_msg(), d); }
-int32_t message::sequence() const { return pn_message_get_group_sequence(message_); }
-void message::sequence(int32_t d) { pn_message_set_group_sequence(message_, d); }
+int32_t message::sequence() const { return pn_message_get_group_sequence(pn_msg()); }
+void message::sequence(int32_t d) { pn_message_set_group_sequence(pn_msg(), d); }
}
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/1622d0e6/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
index 54995c0..9f05d1c 100644
--- a/proton-c/bindings/cpp/src/message_test.cpp
+++ b/proton-c/bindings/cpp/src/message_test.cpp
@@ -18,6 +18,7 @@
*/
#include "proton/message.hpp"
+#include "proton/scalar.hpp"
#include "test_bits.hpp"
#include <string>
#include <fstream>
@@ -32,58 +33,99 @@ using namespace proton;
m.ATTR(#ATTR); \
ASSERT_EQUAL(std::string(#ATTR), m.ATTR())
-#define CHECK_STR_VALUE(ATTR) \
+#define CHECK_MESSAGE_ID(ATTR) \
m.ATTR(#ATTR); \
- ASSERT_EQUAL(std::string(#ATTR), m.ATTR().get<std::string>())
+ ASSERT_EQUAL(scalar(#ATTR), m.ATTR())
-void test_message() {
+void test_message_properties() {
message m("hello");
std::string s = m.body().get<std::string>();
ASSERT_EQUAL("hello", s);
- CHECK_STR_VALUE(id);
+ CHECK_MESSAGE_ID(id);
CHECK_STR(user_id);
CHECK_STR(address);
CHECK_STR(subject);
CHECK_STR(reply_to);
- CHECK_STR_VALUE(correlation_id);
+ CHECK_MESSAGE_ID(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")));
+ message m2(m);
+ ASSERT_EQUAL("hello", m2.body().get<std::string>());
+ ASSERT_EQUAL(message_id("id"), m2.id());
+ ASSERT_EQUAL("user_id", m2.user_id());
+ ASSERT_EQUAL("address", m2.address());
+ ASSERT_EQUAL("subject", m2.subject());
+ ASSERT_EQUAL("reply_to", m2.reply_to());
+ ASSERT_EQUAL(message_id("correlation_id"), m2.correlation_id());
+ ASSERT_EQUAL("content_type", m2.content_type());
+ ASSERT_EQUAL("content_encoding", m2.content_encoding());
+ ASSERT_EQUAL("group_id", m2.group_id());
+ ASSERT_EQUAL("reply_to_group_id", m2.reply_to_group_id());
+ ASSERT_EQUAL(42, m2.expiry_time().milliseconds);
+ ASSERT_EQUAL(4242, m.creation_time().milliseconds);
+
+ m2 = m;
+ ASSERT_EQUAL("hello", m2.body().get<std::string>());
+ ASSERT_EQUAL(message_id("id"), m2.id());
+ ASSERT_EQUAL("user_id", m2.user_id());
+ ASSERT_EQUAL("address", m2.address());
+ ASSERT_EQUAL("subject", m2.subject());
+ ASSERT_EQUAL("reply_to", m2.reply_to());
+ ASSERT_EQUAL(message_id("correlation_id"), m2.correlation_id());
+ ASSERT_EQUAL("content_type", m2.content_type());
+ ASSERT_EQUAL("content_encoding", m2.content_encoding());
+ ASSERT_EQUAL("group_id", m2.group_id());
+ ASSERT_EQUAL("reply_to_group_id", m2.reply_to_group_id());
+ ASSERT_EQUAL(42, m2.expiry_time().milliseconds);
+ ASSERT_EQUAL(4242, m.creation_time().milliseconds);
+}
+
+void test_message_maps() {
+ message m;
+
+ ASSERT(m.properties().empty());
+ ASSERT(m.annotations().empty());
+ ASSERT(m.instructions().empty());
+
+ m.properties()["foo"] = 12;
+ m.instructions()["bar"] = "xyz";
+ m.annotations()[23] = "23";
+
+ ASSERT_EQUAL(m.properties()["foo"], scalar(12));
+ ASSERT_EQUAL(m.instructions()["bar"], scalar("xyz"));
+ ASSERT_EQUAL(m.annotations()[23], scalar("23"));
+
+ message m2(m);
+ message::annotation_map& amap = m2.instructions();
+
+ ASSERT_EQUAL(m2.properties()["foo"], scalar(12));
+ ASSERT_EQUAL(m2.instructions()["bar"], scalar("xyz"));
+ ASSERT_EQUAL(m2.annotations()[23], scalar("23"));
+
+ m.properties()["foo"] = "newfoo";
+ m.instructions()[24] = 1000;
+ m.annotations().erase(23);
+
+ m2 = m;
+ ASSERT_EQUAL(1, m2.properties().size());
+ ASSERT_EQUAL(m2.properties()["foo"], scalar("newfoo"));
+ ASSERT_EQUAL(2, m2.instructions().size());
+ ASSERT_EQUAL(m2.instructions()["bar"], scalar("xyz"));
+ ASSERT_EQUAL(m2.instructions()[24], scalar(1000));
+ ASSERT(m2.annotations().empty());
}
int main(int argc, char** argv) {
int failed = 0;
- RUN_TEST(failed, test_message());
+ RUN_TEST(failed, test_message_properties());
+ RUN_TEST(failed, test_message_maps());
return failed;
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org