| /* |
| * 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 "msg.hpp" |
| #include "types_internal.hpp" |
| |
| #include "proton/binary.hpp" |
| #include "proton/decimal.hpp" |
| #include "proton/internal/type_traits.hpp" |
| #include "proton/scalar_base.hpp" |
| #include "proton/symbol.hpp" |
| #include "proton/timestamp.hpp" |
| #include "proton/uuid.hpp" |
| |
| #include <ostream> |
| #include <sstream> |
| |
| namespace proton { |
| |
| scalar_base::scalar_base() { atom_.type = PN_NULL; } |
| scalar_base::scalar_base(const pn_atom_t& a) { set(a); } |
| scalar_base::scalar_base(const scalar_base& x) { set(x.atom_); } |
| |
| scalar_base& scalar_base::operator=(const scalar_base& x) { |
| if (this != &x) |
| set(x.atom_); |
| return *this; |
| } |
| |
| type_id scalar_base::type() const { return type_id(atom_.type); } |
| |
| bool scalar_base::empty() const { return type() == NULL_TYPE; } |
| |
| void scalar_base::set(const binary& x, pn_type_t t) { |
| atom_.type = t; |
| bytes_ = x; |
| atom_.u.as_bytes = pn_bytes(bytes_); |
| } |
| |
| void scalar_base::set(const pn_atom_t& atom) { |
| if (type_id_is_string_like(type_id(atom.type))) { |
| set(bin(atom.u.as_bytes), atom.type); |
| } else { |
| atom_ = atom; |
| bytes_.clear(); |
| } |
| } |
| |
| void scalar_base::put_(bool x) { atom_.u.as_bool = x; atom_.type = PN_BOOL; } |
| void scalar_base::put_(uint8_t x) { atom_.u.as_ubyte = x; atom_.type = PN_UBYTE; } |
| void scalar_base::put_(int8_t x) { atom_.u.as_byte = x; atom_.type = PN_BYTE; } |
| void scalar_base::put_(uint16_t x) { atom_.u.as_ushort = x; atom_.type = PN_USHORT; } |
| void scalar_base::put_(int16_t x) { atom_.u.as_short = x; atom_.type = PN_SHORT; } |
| void scalar_base::put_(uint32_t x) { atom_.u.as_uint = x; atom_.type = PN_UINT; } |
| void scalar_base::put_(int32_t x) { atom_.u.as_int = x; atom_.type = PN_INT; } |
| void scalar_base::put_(uint64_t x) { atom_.u.as_ulong = x; atom_.type = PN_ULONG; } |
| void scalar_base::put_(int64_t x) { atom_.u.as_long = x; atom_.type = PN_LONG; } |
| void scalar_base::put_(wchar_t x) { atom_.u.as_char = x; atom_.type = PN_CHAR; } |
| void scalar_base::put_(float x) { atom_.u.as_float = x; atom_.type = PN_FLOAT; } |
| void scalar_base::put_(double x) { atom_.u.as_double = x; atom_.type = PN_DOUBLE; } |
| void scalar_base::put_(timestamp x) { atom_.u.as_timestamp = x.milliseconds(); atom_.type = PN_TIMESTAMP; } |
| void scalar_base::put_(const decimal32& x) { byte_copy(atom_.u.as_decimal32, x); atom_.type = PN_DECIMAL32;; } |
| void scalar_base::put_(const decimal64& x) { byte_copy(atom_.u.as_decimal64, x); atom_.type = PN_DECIMAL64; } |
| void scalar_base::put_(const decimal128& x) { byte_copy(atom_.u.as_decimal128, x); atom_.type = PN_DECIMAL128; } |
| void scalar_base::put_(const uuid& x) { byte_copy(atom_.u.as_uuid, x); atom_.type = PN_UUID; } |
| void scalar_base::put_(const std::string& x) { set(binary(x), PN_STRING); } |
| void scalar_base::put_(const symbol& x) { set(binary(x), PN_SYMBOL); } |
| void scalar_base::put_(const binary& x) { set(x, PN_BINARY); } |
| void scalar_base::put_(const char* x) { set(binary(std::string(x)), PN_STRING); } |
| void scalar_base::put_(const null&) { atom_.type = PN_NULL; } |
| #if PN_CPP_HAS_NULLPTR |
| void scalar_base::put_(decltype(nullptr)) { atom_.type = PN_NULL; } |
| #endif |
| |
| |
| void scalar_base::ok(pn_type_t t) const { |
| if (atom_.type != t) throw make_conversion_error(type_id(t), type()); |
| } |
| |
| void scalar_base::get_(bool& x) const { ok(PN_BOOL); x = atom_.u.as_bool; } |
| void scalar_base::get_(uint8_t& x) const { ok(PN_UBYTE); x = atom_.u.as_ubyte; } |
| void scalar_base::get_(int8_t& x) const { ok(PN_BYTE); x = atom_.u.as_byte; } |
| void scalar_base::get_(uint16_t& x) const { ok(PN_USHORT); x = atom_.u.as_ushort; } |
| void scalar_base::get_(int16_t& x) const { ok(PN_SHORT); x = atom_.u.as_short; } |
| void scalar_base::get_(uint32_t& x) const { ok(PN_UINT); x = atom_.u.as_uint; } |
| void scalar_base::get_(int32_t& x) const { ok(PN_INT); x = atom_.u.as_int; } |
| void scalar_base::get_(wchar_t& x) const { ok(PN_CHAR); x = wchar_t(atom_.u.as_char); } |
| void scalar_base::get_(uint64_t& x) const { ok(PN_ULONG); x = atom_.u.as_ulong; } |
| void scalar_base::get_(int64_t& x) const { ok(PN_LONG); x = atom_.u.as_long; } |
| void scalar_base::get_(timestamp& x) const { ok(PN_TIMESTAMP); x = atom_.u.as_timestamp; } |
| void scalar_base::get_(float& x) const { ok(PN_FLOAT); x = atom_.u.as_float; } |
| void scalar_base::get_(double& x) const { ok(PN_DOUBLE); x = atom_.u.as_double; } |
| void scalar_base::get_(decimal32& x) const { ok(PN_DECIMAL32); byte_copy(x, atom_.u.as_decimal32); } |
| void scalar_base::get_(decimal64& x) const { ok(PN_DECIMAL64); byte_copy(x, atom_.u.as_decimal64); } |
| void scalar_base::get_(decimal128& x) const { ok(PN_DECIMAL128); byte_copy(x, atom_.u.as_decimal128); } |
| void scalar_base::get_(uuid& x) const { ok(PN_UUID); byte_copy(x, atom_.u.as_uuid); } |
| void scalar_base::get_(std::string& x) const { ok(PN_STRING); x = std::string(bytes_.begin(), bytes_.end()); } |
| void scalar_base::get_(symbol& x) const { ok(PN_SYMBOL); x = symbol(bytes_.begin(), bytes_.end()); } |
| void scalar_base::get_(binary& x) const { ok(PN_BINARY); x = bytes_; } |
| void scalar_base::get_(null&) const { ok(PN_NULL); } |
| #if PN_CPP_HAS_NULLPTR |
| void scalar_base::get_(decltype(nullptr)&) const { ok(PN_NULL); } |
| #endif |
| |
| namespace { |
| |
| struct equal_op { |
| const scalar_base& x; |
| equal_op(const scalar_base& s) : x(s) {} |
| template<class T> bool operator()(const T& y) { return (internal::get<T>(x) == y); } |
| }; |
| |
| struct less_op { |
| const scalar_base& x; |
| less_op(const scalar_base& s) : x(s) {} |
| template<class T> bool operator()(const T& y) { return (y < internal::get<T>(x)); } |
| }; |
| |
| struct ostream_op { |
| std::ostream& o; |
| ostream_op(std::ostream& o_) : o(o_) {} |
| template<class T> std::ostream& operator()(const T& x) { return o << x; } |
| }; |
| |
| } // namespace |
| |
| bool operator==(const scalar_base& x, const scalar_base& y) { |
| if (x.type() != y.type()) return false; |
| if (x.type() == NULL_TYPE) return true; |
| return internal::visit<bool>(x, equal_op(y)); |
| } |
| |
| bool operator<(const scalar_base& x, const scalar_base& y) { |
| if (x.type() != y.type()) return x.type() < y.type(); |
| if (x.type() == NULL_TYPE) return false; |
| return internal::visit<bool>(x, less_op(y)); |
| } |
| |
| std::ostream& operator<<(std::ostream& o, const scalar_base& s) { |
| switch (s.type()) { |
| case NULL_TYPE: return o << "null"; |
| case BYTE: return o << static_cast<int>(internal::get<int8_t>(s)); |
| case UBYTE: return o << static_cast<unsigned int>(internal::get<uint8_t>(s)); |
| // Other types printed using normal C++ operator << |
| default: return internal::visit<std::ostream&>(s, ostream_op(o)); |
| } |
| } |
| |
| namespace internal { |
| |
| conversion_error make_coercion_error(const char* cpp, type_id amqp) { |
| return conversion_error(std::string("invalid proton::coerce<") + cpp + ">(" + type_name(amqp) + ")"); |
| } |
| |
| } // internal |
| |
| std::string to_string(const scalar_base& x) { |
| std::ostringstream os; |
| os << std::boolalpha << x; |
| return os.str(); |
| } |
| |
| } // proton |