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/30 22:13:33 UTC

[45/50] [abbrv] qpid-proton git commit: PROTON-1085: c++: clean up access to message properties, instructions and annotations.

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