Hideaki Tai / msgpack-embedded

Dependents:   hello_message_pack

Committer:
hideakitai
Date:
Mon Feb 22 01:43:48 2016 +0000
Revision:
4:bd0c06dd6e92
Parent:
0:3f9dbf1e2cb0
fix throw error

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hideakitai 0:3f9dbf1e2cb0 1 //
hideakitai 0:3f9dbf1e2cb0 2 // MessagePack for C++ static resolution routine
hideakitai 0:3f9dbf1e2cb0 3 //
hideakitai 0:3f9dbf1e2cb0 4 // Copyright (C) 2015 KONDO Takatoshi
hideakitai 0:3f9dbf1e2cb0 5 //
hideakitai 0:3f9dbf1e2cb0 6 // Distributed under the Boost Software License, Version 1.0.
hideakitai 0:3f9dbf1e2cb0 7 // (See accompanying file LICENSE_1_0.txt or copy at
hideakitai 0:3f9dbf1e2cb0 8 // http://www.boost.org/LICENSE_1_0.txt)
hideakitai 0:3f9dbf1e2cb0 9 //
hideakitai 0:3f9dbf1e2cb0 10 #ifndef MSGPACK_TYPE_EXT_HPP
hideakitai 0:3f9dbf1e2cb0 11 #define MSGPACK_TYPE_EXT_HPP
hideakitai 0:3f9dbf1e2cb0 12
hideakitai 0:3f9dbf1e2cb0 13 #include "msgpack/versioning.hpp"
hideakitai 0:3f9dbf1e2cb0 14 #include "msgpack/adaptor/adaptor_base.hpp"
hideakitai 0:3f9dbf1e2cb0 15 #include <cstring>
hideakitai 0:3f9dbf1e2cb0 16 #include <string>
hideakitai 0:3f9dbf1e2cb0 17 #include <cassert>
hideakitai 0:3f9dbf1e2cb0 18
hideakitai 0:3f9dbf1e2cb0 19 namespace msgpack {
hideakitai 0:3f9dbf1e2cb0 20
hideakitai 0:3f9dbf1e2cb0 21 /// @cond
hideakitai 0:3f9dbf1e2cb0 22 MSGPACK_API_VERSION_NAMESPACE(v1) {
hideakitai 0:3f9dbf1e2cb0 23 /// @endcond
hideakitai 0:3f9dbf1e2cb0 24
hideakitai 0:3f9dbf1e2cb0 25 namespace type {
hideakitai 0:3f9dbf1e2cb0 26 class ext_ref;
hideakitai 0:3f9dbf1e2cb0 27
hideakitai 0:3f9dbf1e2cb0 28 class ext {
hideakitai 0:3f9dbf1e2cb0 29 public:
hideakitai 0:3f9dbf1e2cb0 30 ext() : m_data(1, 0) {}
hideakitai 0:3f9dbf1e2cb0 31 ext(int8_t t, const char* p, uint32_t s) {
hideakitai 0:3f9dbf1e2cb0 32 detail::check_container_size_for_ext<sizeof(std::size_t)>(s);
hideakitai 0:3f9dbf1e2cb0 33 m_data.reserve(static_cast<std::size_t>(s) + 1);
hideakitai 0:3f9dbf1e2cb0 34 m_data.push_back(static_cast<char>(t));
hideakitai 0:3f9dbf1e2cb0 35 m_data.insert(m_data.end(), p, p + s);
hideakitai 0:3f9dbf1e2cb0 36 }
hideakitai 0:3f9dbf1e2cb0 37 ext(int8_t t, uint32_t s) {
hideakitai 0:3f9dbf1e2cb0 38 detail::check_container_size_for_ext<sizeof(std::size_t)>(s);
hideakitai 0:3f9dbf1e2cb0 39 m_data.resize(static_cast<std::size_t>(s) + 1);
hideakitai 0:3f9dbf1e2cb0 40 m_data[0] = static_cast<char>(t);
hideakitai 0:3f9dbf1e2cb0 41 }
hideakitai 0:3f9dbf1e2cb0 42 ext(ext_ref const&);
hideakitai 0:3f9dbf1e2cb0 43 int8_t type() const {
hideakitai 0:3f9dbf1e2cb0 44 return static_cast<int8_t>(m_data[0]);
hideakitai 0:3f9dbf1e2cb0 45 }
hideakitai 0:3f9dbf1e2cb0 46 const char* data() const {
hideakitai 0:3f9dbf1e2cb0 47 return &m_data[1];
hideakitai 0:3f9dbf1e2cb0 48 }
hideakitai 0:3f9dbf1e2cb0 49 char* data() {
hideakitai 0:3f9dbf1e2cb0 50 return &m_data[1];
hideakitai 0:3f9dbf1e2cb0 51 }
hideakitai 0:3f9dbf1e2cb0 52 uint32_t size() const {
hideakitai 0:3f9dbf1e2cb0 53 return static_cast<uint32_t>(m_data.size()) - 1;
hideakitai 0:3f9dbf1e2cb0 54 }
hideakitai 0:3f9dbf1e2cb0 55 bool operator== (const ext& x) const {
hideakitai 0:3f9dbf1e2cb0 56 return m_data == x.m_data;
hideakitai 0:3f9dbf1e2cb0 57 }
hideakitai 0:3f9dbf1e2cb0 58
hideakitai 0:3f9dbf1e2cb0 59 bool operator!= (const ext& x) const {
hideakitai 0:3f9dbf1e2cb0 60 return !(*this == x);
hideakitai 0:3f9dbf1e2cb0 61 }
hideakitai 0:3f9dbf1e2cb0 62
hideakitai 0:3f9dbf1e2cb0 63 bool operator< (const ext& x) const {
hideakitai 0:3f9dbf1e2cb0 64 return m_data < x.m_data;
hideakitai 0:3f9dbf1e2cb0 65 }
hideakitai 0:3f9dbf1e2cb0 66
hideakitai 0:3f9dbf1e2cb0 67 bool operator> (const ext& x) const {
hideakitai 0:3f9dbf1e2cb0 68 return m_data > x.m_data;
hideakitai 0:3f9dbf1e2cb0 69 }
hideakitai 0:3f9dbf1e2cb0 70 private:
hideakitai 0:3f9dbf1e2cb0 71 std::vector<char> m_data;
hideakitai 0:3f9dbf1e2cb0 72 friend class ext_ref;
hideakitai 0:3f9dbf1e2cb0 73 };
hideakitai 0:3f9dbf1e2cb0 74
hideakitai 0:3f9dbf1e2cb0 75 } // namespace type
hideakitai 0:3f9dbf1e2cb0 76
hideakitai 0:3f9dbf1e2cb0 77 namespace adaptor {
hideakitai 0:3f9dbf1e2cb0 78
hideakitai 0:3f9dbf1e2cb0 79 template <>
hideakitai 0:3f9dbf1e2cb0 80 struct convert<msgpack::type::ext> {
hideakitai 0:3f9dbf1e2cb0 81 msgpack::object const& operator()(msgpack::object const& o, msgpack::type::ext& v) const {
hideakitai 0:3f9dbf1e2cb0 82 if(o.type != msgpack::type::EXT) {
hideakitai 0:3f9dbf1e2cb0 83 // throw msgpack::type_error();
hideakitai 0:3f9dbf1e2cb0 84 }
hideakitai 0:3f9dbf1e2cb0 85 v = msgpack::type::ext(o.via.ext.type(), o.via.ext.data(), o.via.ext.size);
hideakitai 0:3f9dbf1e2cb0 86 return o;
hideakitai 0:3f9dbf1e2cb0 87 }
hideakitai 0:3f9dbf1e2cb0 88 };
hideakitai 0:3f9dbf1e2cb0 89
hideakitai 0:3f9dbf1e2cb0 90 template <>
hideakitai 0:3f9dbf1e2cb0 91 struct pack<msgpack::type::ext> {
hideakitai 0:3f9dbf1e2cb0 92 template <typename Stream>
hideakitai 0:3f9dbf1e2cb0 93 msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, const msgpack::type::ext& v) const {
hideakitai 0:3f9dbf1e2cb0 94 // size limit has already been checked at ext's constructor
hideakitai 0:3f9dbf1e2cb0 95 uint32_t size = v.size();
hideakitai 0:3f9dbf1e2cb0 96 o.pack_ext(size, v.type());
hideakitai 0:3f9dbf1e2cb0 97 o.pack_ext_body(v.data(), size);
hideakitai 0:3f9dbf1e2cb0 98 return o;
hideakitai 0:3f9dbf1e2cb0 99 }
hideakitai 0:3f9dbf1e2cb0 100 };
hideakitai 0:3f9dbf1e2cb0 101
hideakitai 0:3f9dbf1e2cb0 102 template <>
hideakitai 0:3f9dbf1e2cb0 103 struct object_with_zone<msgpack::type::ext> {
hideakitai 0:3f9dbf1e2cb0 104 void operator()(msgpack::object::with_zone& o, const msgpack::type::ext& v) const {
hideakitai 0:3f9dbf1e2cb0 105 // size limit has already been checked at ext's constructor
hideakitai 0:3f9dbf1e2cb0 106 uint32_t size = v.size();
hideakitai 0:3f9dbf1e2cb0 107 o.type = msgpack::type::EXT;
hideakitai 0:3f9dbf1e2cb0 108 char* ptr = static_cast<char*>(o.zone.allocate_align(size + 1));
hideakitai 0:3f9dbf1e2cb0 109 o.via.ext.ptr = ptr;
hideakitai 0:3f9dbf1e2cb0 110 o.via.ext.size = size;
hideakitai 0:3f9dbf1e2cb0 111 ptr[0] = static_cast<char>(v.type());
hideakitai 0:3f9dbf1e2cb0 112 std::memcpy(ptr + 1, v.data(), size);
hideakitai 0:3f9dbf1e2cb0 113 }
hideakitai 0:3f9dbf1e2cb0 114 };
hideakitai 0:3f9dbf1e2cb0 115
hideakitai 0:3f9dbf1e2cb0 116 } // namespace adaptor
hideakitai 0:3f9dbf1e2cb0 117
hideakitai 0:3f9dbf1e2cb0 118 namespace type {
hideakitai 0:3f9dbf1e2cb0 119
hideakitai 0:3f9dbf1e2cb0 120 class ext_ref {
hideakitai 0:3f9dbf1e2cb0 121 public:
hideakitai 0:3f9dbf1e2cb0 122 // ext_ref should be default constructible to support 'convert'.
hideakitai 0:3f9dbf1e2cb0 123 // A default constructed ext_ref object::m_ptr doesn't have the buffer to point to.
hideakitai 0:3f9dbf1e2cb0 124 // In order to avoid nullptr checking branches, m_ptr points to m_size.
hideakitai 0:3f9dbf1e2cb0 125 // So type() returns unspecified but valid value. It might be a zero because m_size
hideakitai 0:3f9dbf1e2cb0 126 // is initialized as zero, but shouldn't assume that.
hideakitai 0:3f9dbf1e2cb0 127 ext_ref() : m_ptr(static_cast<char*>(static_cast<void*>(&m_size))), m_size(0) {}
hideakitai 0:3f9dbf1e2cb0 128 ext_ref(const char* p, uint32_t s) :
hideakitai 0:3f9dbf1e2cb0 129 m_ptr(s == 0 ? static_cast<char*>(static_cast<void*>(&m_size)) : p),
hideakitai 0:3f9dbf1e2cb0 130 m_size(s == 0 ? 0 : s - 1) {
hideakitai 0:3f9dbf1e2cb0 131 detail::check_container_size_for_ext<sizeof(std::size_t)>(s);
hideakitai 0:3f9dbf1e2cb0 132 }
hideakitai 0:3f9dbf1e2cb0 133
hideakitai 0:3f9dbf1e2cb0 134 // size limit has already been checked at ext's constructor
hideakitai 0:3f9dbf1e2cb0 135 ext_ref(ext const& x) : m_ptr(&x.m_data[0]), m_size(x.size()) {}
hideakitai 0:3f9dbf1e2cb0 136
hideakitai 0:3f9dbf1e2cb0 137 const char* data() const {
hideakitai 0:3f9dbf1e2cb0 138 return m_ptr + 1;
hideakitai 0:3f9dbf1e2cb0 139 }
hideakitai 0:3f9dbf1e2cb0 140
hideakitai 0:3f9dbf1e2cb0 141 uint32_t size() const {
hideakitai 0:3f9dbf1e2cb0 142 return m_size;
hideakitai 0:3f9dbf1e2cb0 143 }
hideakitai 0:3f9dbf1e2cb0 144
hideakitai 0:3f9dbf1e2cb0 145 int8_t type() const {
hideakitai 0:3f9dbf1e2cb0 146 return static_cast<int8_t>(m_ptr[0]);
hideakitai 0:3f9dbf1e2cb0 147 }
hideakitai 0:3f9dbf1e2cb0 148
hideakitai 0:3f9dbf1e2cb0 149 std::string str() const {
hideakitai 0:3f9dbf1e2cb0 150 return std::string(m_ptr + 1, m_size);
hideakitai 0:3f9dbf1e2cb0 151 }
hideakitai 0:3f9dbf1e2cb0 152
hideakitai 0:3f9dbf1e2cb0 153 bool operator== (const ext_ref& x) const {
hideakitai 0:3f9dbf1e2cb0 154 return m_size == x.m_size && std::memcmp(m_ptr, x.m_ptr, m_size) == 0;
hideakitai 0:3f9dbf1e2cb0 155 }
hideakitai 0:3f9dbf1e2cb0 156
hideakitai 0:3f9dbf1e2cb0 157 bool operator!= (const ext_ref& x) const {
hideakitai 0:3f9dbf1e2cb0 158 return !(*this == x);
hideakitai 0:3f9dbf1e2cb0 159 }
hideakitai 0:3f9dbf1e2cb0 160
hideakitai 0:3f9dbf1e2cb0 161 bool operator< (const ext_ref& x) const {
hideakitai 0:3f9dbf1e2cb0 162 if (m_size < x.m_size) return true;
hideakitai 0:3f9dbf1e2cb0 163 if (m_size > x.m_size) return false;
hideakitai 0:3f9dbf1e2cb0 164 return std::memcmp(m_ptr, x.m_ptr, m_size) < 0;
hideakitai 0:3f9dbf1e2cb0 165 }
hideakitai 0:3f9dbf1e2cb0 166
hideakitai 0:3f9dbf1e2cb0 167 bool operator> (const ext_ref& x) const {
hideakitai 0:3f9dbf1e2cb0 168 if (m_size > x.m_size) return true;
hideakitai 0:3f9dbf1e2cb0 169 if (m_size < x.m_size) return false;
hideakitai 0:3f9dbf1e2cb0 170 return std::memcmp(m_ptr, x.m_ptr, m_size) > 0;
hideakitai 0:3f9dbf1e2cb0 171 }
hideakitai 0:3f9dbf1e2cb0 172 private:
hideakitai 0:3f9dbf1e2cb0 173 const char* m_ptr;
hideakitai 0:3f9dbf1e2cb0 174 uint32_t m_size;
hideakitai 0:3f9dbf1e2cb0 175 friend struct msgpack::adaptor::object<msgpack::type::ext_ref>;
hideakitai 0:3f9dbf1e2cb0 176 };
hideakitai 0:3f9dbf1e2cb0 177
hideakitai 0:3f9dbf1e2cb0 178 inline ext::ext(ext_ref const& x) {
hideakitai 0:3f9dbf1e2cb0 179 // size limit has already been checked at ext_ref's constructor
hideakitai 0:3f9dbf1e2cb0 180 m_data.reserve(x.size() + 1);
hideakitai 0:3f9dbf1e2cb0 181
hideakitai 0:3f9dbf1e2cb0 182 m_data.push_back(x.type());
hideakitai 0:3f9dbf1e2cb0 183 m_data.insert(m_data.end(), x.data(), x.data() + x.size());
hideakitai 0:3f9dbf1e2cb0 184 }
hideakitai 0:3f9dbf1e2cb0 185
hideakitai 0:3f9dbf1e2cb0 186 } // namespace type
hideakitai 0:3f9dbf1e2cb0 187
hideakitai 0:3f9dbf1e2cb0 188 namespace adaptor {
hideakitai 0:3f9dbf1e2cb0 189
hideakitai 0:3f9dbf1e2cb0 190 template <>
hideakitai 0:3f9dbf1e2cb0 191 struct convert<msgpack::type::ext_ref> {
hideakitai 0:3f9dbf1e2cb0 192 msgpack::object const& operator()(msgpack::object const& o, msgpack::type::ext_ref& v) const {
hideakitai 0:3f9dbf1e2cb0 193 if(o.type != msgpack::type::EXT) {
hideakitai 0:3f9dbf1e2cb0 194 // throw msgpack::type_error();
hideakitai 0:3f9dbf1e2cb0 195 }
hideakitai 0:3f9dbf1e2cb0 196 v = msgpack::type::ext_ref(o.via.ext.ptr, o.via.ext.size + 1);
hideakitai 0:3f9dbf1e2cb0 197 return o;
hideakitai 0:3f9dbf1e2cb0 198 }
hideakitai 0:3f9dbf1e2cb0 199 };
hideakitai 0:3f9dbf1e2cb0 200
hideakitai 0:3f9dbf1e2cb0 201 template <>
hideakitai 0:3f9dbf1e2cb0 202 struct pack<msgpack::type::ext_ref> {
hideakitai 0:3f9dbf1e2cb0 203 template <typename Stream>
hideakitai 0:3f9dbf1e2cb0 204 msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, const msgpack::type::ext_ref& v) const {
hideakitai 0:3f9dbf1e2cb0 205 // size limit has already been checked at ext_ref's constructor
hideakitai 0:3f9dbf1e2cb0 206 uint32_t size = v.size();
hideakitai 0:3f9dbf1e2cb0 207 o.pack_ext(size, v.type());
hideakitai 0:3f9dbf1e2cb0 208 o.pack_ext_body(v.data(), size);
hideakitai 0:3f9dbf1e2cb0 209 return o;
hideakitai 0:3f9dbf1e2cb0 210 }
hideakitai 0:3f9dbf1e2cb0 211 };
hideakitai 0:3f9dbf1e2cb0 212
hideakitai 0:3f9dbf1e2cb0 213 template <>
hideakitai 0:3f9dbf1e2cb0 214 struct object<msgpack::type::ext_ref> {
hideakitai 0:3f9dbf1e2cb0 215 void operator()(msgpack::object& o, const msgpack::type::ext_ref& v) const {
hideakitai 0:3f9dbf1e2cb0 216 // size limit has already been checked at ext_ref's constructor
hideakitai 0:3f9dbf1e2cb0 217 uint32_t size = v.size();
hideakitai 0:3f9dbf1e2cb0 218 o.type = msgpack::type::EXT;
hideakitai 0:3f9dbf1e2cb0 219 o.via.ext.ptr = v.m_ptr;
hideakitai 0:3f9dbf1e2cb0 220 o.via.ext.size = size;
hideakitai 0:3f9dbf1e2cb0 221 }
hideakitai 0:3f9dbf1e2cb0 222 };
hideakitai 0:3f9dbf1e2cb0 223
hideakitai 0:3f9dbf1e2cb0 224 template <>
hideakitai 0:3f9dbf1e2cb0 225 struct object_with_zone<msgpack::type::ext_ref> {
hideakitai 0:3f9dbf1e2cb0 226 void operator()(msgpack::object::with_zone& o, const msgpack::type::ext_ref& v) const {
hideakitai 0:3f9dbf1e2cb0 227 static_cast<msgpack::object&>(o) << v;
hideakitai 0:3f9dbf1e2cb0 228 }
hideakitai 0:3f9dbf1e2cb0 229 };
hideakitai 0:3f9dbf1e2cb0 230
hideakitai 0:3f9dbf1e2cb0 231 } // namespace adaptor
hideakitai 0:3f9dbf1e2cb0 232
hideakitai 0:3f9dbf1e2cb0 233 /// @cond
hideakitai 0:3f9dbf1e2cb0 234 } // MSGPACK_API_VERSION_NAMESPACE(v1)
hideakitai 0:3f9dbf1e2cb0 235 /// @endcond
hideakitai 0:3f9dbf1e2cb0 236
hideakitai 0:3f9dbf1e2cb0 237 } // namespace msgpack
hideakitai 0:3f9dbf1e2cb0 238
hideakitai 0:3f9dbf1e2cb0 239 #endif // MSGPACK_TYPE_EXT_HPP