blob: 7a38f12c17bfb2070428d56a4837b81a90776e09 [file] [log] [blame]
/*
* 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/codec.h>
#include <ostream>
#include <iomanip>
#include <algorithm>
#include <sstream>
namespace proton {
namespace {
inline std::ostream& print_segment(std::ostream& o, const amqp_uuid& u, size_t begin, size_t end, const char* sep="") {
for (const char* p = &u[begin]; p < &u[end]; ++p)
o << std::setw(2) << std::setfill('0') << (int(*p) & 0xff);
return o << sep;
}
std::string mismatch_message(type_id want, type_id got, const std::string& msg=std::string()) {
std::ostringstream s;
s << "want " << want << " got " << got;
if (!msg.empty()) s << ": " << msg;
return s.str();
}
} // namespace
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>"; }
std::ostream& operator<<(std::ostream& o, const amqp_timestamp& ts) { return o << "timestamp:" << ts.milliseconds; }
std::ostream& operator<<(std::ostream& o, const amqp_uuid& u) {
std::ios_base::fmtflags ff = o.flags();
o.flags(std::ios_base::hex);
print_segment(o, u, 0, 4, "-");
print_segment(o, u, 4, 6, "-");
print_segment(o, u, 6, 8, "-");
print_segment(o, u, 8, 10, "-");
print_segment(o, u, 10, 16);
o.flags(ff);
return o;
}
std::string type_name(type_id t) {
switch (t) {
case NULL_TYPE: return "null";
case BOOLEAN: return "boolean";
case UBYTE: return "ubyte";
case BYTE: return "byte";
case USHORT: return "ushort";
case SHORT: return "short";
case UINT: return "uint";
case INT: return "int";
case CHAR: return "char";
case ULONG: return "ulong";
case LONG: return "long";
case TIMESTAMP: return "timestamp";
case FLOAT: return "float";
case DOUBLE: return "double";
case DECIMAL32: return "decimal32";
case DECIMAL64: return "decimal64";
case DECIMAL128: return "decimal128";
case UUID: return "uuid";
case BINARY: return "binary";
case STRING: return "string";
case SYMBOL: return "symbol";
case DESCRIBED: return "described";
case ARRAY: return "array";
case LIST: return "list";
case MAP: return "map";
}
return "unknown";
}
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); }
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); }
pn_bytes_t pn_bytes(const std::string& s) {
pn_bytes_t b = { s.size(), const_cast<char*>(&s[0]) };
return b;
}
std::string str(const pn_bytes_t& b) { return std::string(b.start, b.size); }
start::start(type_id t, type_id e, bool d, size_t s) : type(t), element(e), is_described(d), size(s) {}
start start::array(type_id element, bool described) { return start(ARRAY, element, described); }
start start::list() { return start(LIST); }
start start::map() { return start(MAP); }
start start::described() { return start(DESCRIBED, NULL_TYPE, true); }
}