123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253 |
- //
- // MessagePack for C++ static resolution routine
- //
- // Copyright (C) 2016 KONDO Takatoshi
- //
- // Distributed under the Boost Software License, Version 1.0.
- // (See accompanying file LICENSE_1_0.txt or copy at
- // http://www.boost.org/LICENSE_1_0.txt)
- //
- #ifndef MSGPACK_V1_TYPE_CARRAY_HPP
- #define MSGPACK_V1_TYPE_CARRAY_HPP
- #include "msgpack/versioning.hpp"
- #include "msgpack/object_fwd.hpp"
- #include "msgpack/adaptor/adaptor_base.hpp"
- #include "msgpack/adaptor/check_container_size.hpp"
- namespace msgpack {
- /// @cond
- MSGPACK_API_VERSION_NAMESPACE(v1) {
- /// @endcond
- namespace adaptor {
- template <typename T, std::size_t N>
- struct convert<T[N]> {
- msgpack::object const& operator()(msgpack::object const& o, T* v) const {
- if (o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); }
- if (o.via.array.size > N) { throw msgpack::type_error(); }
- msgpack::object* p = o.via.array.ptr;
- msgpack::object* const pend = o.via.array.ptr + o.via.array.size;
- do {
- p->convert(*v);
- ++p;
- ++v;
- } while(p < pend);
- return o;
- }
- };
- template <std::size_t N>
- struct convert<char[N]> {
- msgpack::object const& operator()(msgpack::object const& o, char(&v)[N]) const {
- switch (o.type) {
- case msgpack::type::BIN:
- if (o.via.bin.size > N) { throw msgpack::type_error(); }
- std::memcpy(v, o.via.bin.ptr, o.via.bin.size);
- break;
- case msgpack::type::STR:
- if (o.via.str.size > N) { throw msgpack::type_error(); }
- std::memcpy(v, o.via.str.ptr, o.via.str.size);
- if (o.via.str.size < N) v[o.via.str.size] = '\0';
- break;
- default:
- throw msgpack::type_error();
- break;
- }
- return o;
- }
- };
- template <std::size_t N>
- struct convert<unsigned char[N]> {
- msgpack::object const& operator()(msgpack::object const& o, unsigned char(&v)[N]) const {
- switch (o.type) {
- case msgpack::type::BIN:
- if (o.via.bin.size > N) { throw msgpack::type_error(); }
- std::memcpy(v, o.via.bin.ptr, o.via.bin.size);
- break;
- case msgpack::type::STR:
- if (o.via.str.size > N) { throw msgpack::type_error(); }
- std::memcpy(v, o.via.str.ptr, o.via.str.size);
- if (o.via.str.size < N) v[o.via.str.size] = '\0';
- break;
- default:
- throw msgpack::type_error();
- break;
- }
- return o;
- }
- };
- template <typename T, std::size_t N>
- struct pack<T[N]> {
- template <typename Stream>
- msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, const T(&v)[N]) const {
- uint32_t size = checked_get_container_size(N);
- o.pack_array(size);
- const T* ptr = v;
- for (; ptr != &v[N]; ++ptr) o.pack(*ptr);
- return o;
- }
- };
- template <std::size_t N>
- struct pack<char[N]> {
- template <typename Stream>
- msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, const char(&v)[N]) const {
- char const* p = v;
- uint32_t size = checked_get_container_size(N);
- char const* p2 = static_cast<char const*>(std::memchr(p, '\0', size));
- uint32_t adjusted_size = p2 ? static_cast<uint32_t>(p2 - p) : size;
- o.pack_str(adjusted_size);
- o.pack_str_body(p, adjusted_size);
- return o;
- }
- };
- template <std::size_t N>
- struct pack<const char[N]> {
- template <typename Stream>
- msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, const char(&v)[N]) const {
- uint32_t size = checked_get_container_size(N);
- char const* p = v;
- char const* p2 = static_cast<char const*>(std::memchr(p, '\0', size));
- uint32_t adjusted_size = p2 ? static_cast<uint32_t>(p2 - p) : size;
- o.pack_str(adjusted_size);
- o.pack_str_body(p, adjusted_size);
- return o;
- }
- };
- template <std::size_t N>
- struct pack<unsigned char[N]> {
- template <typename Stream>
- msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, const unsigned char(&v)[N]) const {
- unsigned char const* p = v;
- uint32_t size = checked_get_container_size(N);
- o.pack_bin(size);
- o.pack_bin_body(reinterpret_cast<char const*>(p), size);
- return o;
- }
- };
- template <std::size_t N>
- struct pack<const unsigned char[N]> {
- template <typename Stream>
- msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, const unsigned char(&v)[N]) const {
- unsigned char const* p = v;
- uint32_t size = checked_get_container_size(N);
- o.pack_bin(size);
- o.pack_bin_body(reinterpret_cast<char const*>(p), size);
- return o;
- }
- };
- template <typename T, std::size_t N>
- struct object_with_zone<T[N]> {
- void operator()(msgpack::object::with_zone& o, const T(&v)[N]) const {
- uint32_t size = checked_get_container_size(N);
- o.type = msgpack::type::ARRAY;
- msgpack::object* ptr = static_cast<msgpack::object*>(o.zone.allocate_align(sizeof(msgpack::object) * size, MSGPACK_ZONE_ALIGNOF(msgpack::object)));
- o.via.array.ptr = ptr;
- o.via.array.size = size;
- const T* pv = v;
- for (; pv != &v[size]; ++pv) {
- *ptr++ = msgpack::object(*pv, o.zone);
- }
- }
- };
- template <std::size_t N>
- struct object_with_zone<char[N]> {
- void operator()(msgpack::object::with_zone& o, const char(&v)[N]) const {
- char const* p = v;
- uint32_t size = checked_get_container_size(N);
- char const* p2 = static_cast<char const*>(std::memchr(p, '\0', size));
- uint32_t adjusted_size = p2 ? static_cast<uint32_t>(p2 - p) : size;
- o.type = msgpack::type::STR;
- char* ptr = static_cast<char*>(o.zone.allocate_align(adjusted_size, MSGPACK_ZONE_ALIGNOF(char)));
- o.via.str.ptr = ptr;
- o.via.str.size = adjusted_size;
- std::memcpy(ptr, p, adjusted_size);
- }
- };
- template <std::size_t N>
- struct object_with_zone<const char[N]> {
- void operator()(msgpack::object::with_zone& o, const char(&v)[N]) const {
- char const* p = v;
- uint32_t size = checked_get_container_size(N);
- char const* p2 = static_cast<char const*>(std::memchr(p, '\0', size));
- uint32_t adjusted_size = p2 ? static_cast<uint32_t>(p2 - p) : size;
- o.type = msgpack::type::STR;
- char* ptr = static_cast<char*>(o.zone.allocate_align(adjusted_size, MSGPACK_ZONE_ALIGNOF(char)));
- o.via.str.ptr = ptr;
- o.via.str.size = adjusted_size;
- std::memcpy(ptr, p, adjusted_size);
- }
- };
- template <std::size_t N>
- struct object_with_zone<unsigned char[N]> {
- void operator()(msgpack::object::with_zone& o, const unsigned char(&v)[N]) const {
- uint32_t size = checked_get_container_size(N);
- o.type = msgpack::type::BIN;
- char* ptr = static_cast<char*>(o.zone.allocate_align(size, MSGPACK_ZONE_ALIGNOF(char)));
- o.via.bin.ptr = ptr;
- o.via.bin.size = size;
- std::memcpy(ptr, v, size);
- }
- };
- template <std::size_t N>
- struct object_with_zone<const unsigned char[N]> {
- void operator()(msgpack::object::with_zone& o, const unsigned char(&v)[N]) const {
- uint32_t size = checked_get_container_size(N);
- o.type = msgpack::type::BIN;
- char* ptr = static_cast<char*>(o.zone.allocate_align(size, MSGPACK_ZONE_ALIGNOF(char)));
- o.via.bin.ptr = ptr;
- o.via.bin.size = size;
- std::memcpy(ptr, v, size);
- }
- };
- template <std::size_t N>
- struct object<char[N]> {
- void operator()(msgpack::object& o, const char(&v)[N]) const {
- char const* p = v;
- uint32_t size = checked_get_container_size(N);
- char const* p2 = static_cast<char const*>(std::memchr(p, '\0', size));
- uint32_t adjusted_size = p2 ? static_cast<uint32_t>(p2 - p) : size;
- o.type = msgpack::type::STR;
- o.via.str.ptr = p;
- o.via.str.size = adjusted_size;
- }
- };
- template <std::size_t N>
- struct object<const char[N]> {
- void operator()(msgpack::object& o, const char(&v)[N]) const {
- char const* p = v;
- uint32_t size = checked_get_container_size(N);
- char const* p2 = static_cast<char const*>(std::memchr(p, '\0', size));
- uint32_t adjusted_size = p2 ? static_cast<uint32_t>(p2 - p) : size;
- o.type = msgpack::type::STR;
- o.via.str.ptr = p;
- o.via.str.size = adjusted_size;
- }
- };
- } // namespace adaptor
- /// @cond
- } // MSGPACK_API_VERSION_NAMESPACE(v1)
- /// @endcond
- } // namespace msgpack
- #endif // MSGPACK_V1_TYPE_CARRAY_HPP
|