diff --git a/CMakeLists.txt b/CMakeLists.txt index 2cdbf22a..4e29263c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -130,6 +130,7 @@ IF (MSGPACK_ENABLE_CXX) include/msgpack/adaptor/nil.hpp include/msgpack/adaptor/pair.hpp include/msgpack/adaptor/raw.hpp + include/msgpack/adaptor/v4raw.hpp include/msgpack/adaptor/set.hpp include/msgpack/adaptor/string.hpp include/msgpack/adaptor/tr1/unordered_map.hpp diff --git a/include/msgpack/adaptor/v4raw.hpp b/include/msgpack/adaptor/v4raw.hpp new file mode 100644 index 00000000..c1bb4c91 --- /dev/null +++ b/include/msgpack/adaptor/v4raw.hpp @@ -0,0 +1,114 @@ +// +// MessagePack for C++ static resolution routine +// +// Copyright (C) 2008-2015 FURUHASHI Sadayuki and KONDO Takatoshi +// +// Licensed 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. +// +#ifndef MSGPACK_TYPE_V4RAW_HPP +#define MSGPACK_TYPE_V4RAW_HPP + +#include "msgpack/versioning.hpp" +#include "msgpack/adaptor/adaptor_base.hpp" +#include +#include + +namespace msgpack { + +/// @cond +MSGPACK_API_VERSION_NAMESPACE(v1) { +/// @endcond + +namespace type { + +struct v4raw_ref { + v4raw_ref() : size(0), ptr(nullptr) {} + v4raw_ref(const char* p, uint32_t s) : size(s), ptr(p) {} + + uint32_t size; + const char* ptr; + + std::string str() const { return std::string(ptr, size); } + + bool operator== (const v4raw_ref& x) const + { + return size == x.size && std::memcmp(ptr, x.ptr, size) == 0; + } + + bool operator!= (const v4raw_ref& x) const + { + return !(*this == x); + } + + bool operator< (const v4raw_ref& x) const + { + if(size == x.size) { return std::memcmp(ptr, x.ptr, size) < 0; } + else { return size < x.size; } + } + + bool operator> (const v4raw_ref& x) const + { + if(size == x.size) { return std::memcmp(ptr, x.ptr, size) > 0; } + else { return size > x.size; } + } +}; + +} // namespace type + +namespace adaptor { + +template <> +struct convert { + msgpack::object const& operator()(msgpack::object const& o, msgpack::type::v4raw_ref& v) const { + if(o.type != msgpack::type::STR) { throw msgpack::type_error(); } + v.ptr = o.via.str.ptr; + v.size = o.via.str.size; + return o; + } +}; + +template <> +struct pack { + template + msgpack::packer& operator()(msgpack::packer& o, const msgpack::type::v4raw_ref& v) const { + o.pack_v4raw(v.size); + o.pack_v4raw_body(v.ptr, v.size); + return o; + } +}; + +template <> +struct object { + void operator()(msgpack::object& o, const msgpack::type::v4raw_ref& v) const { + o.type = msgpack::type::STR; + o.via.str.ptr = v.ptr; + o.via.str.size = v.size; + } +}; + +template <> +struct object_with_zone { + void operator()(msgpack::object::with_zone& o, const msgpack::type::v4raw_ref& v) const { + static_cast(o) << v; + } +}; + +} // namespace adaptor + +/// @cond +} // MSGPACK_API_VERSION_NAMESPACE(v1) +/// @endcond + +} // namespace msgpack + +#endif // MSGPACK_TYPE_V4RAW_HPP diff --git a/include/msgpack/pack.h b/include/msgpack/pack.h index ea0fbf70..ec25bac9 100644 --- a/include/msgpack/pack.h +++ b/include/msgpack/pack.h @@ -97,6 +97,9 @@ static int msgpack_pack_map(msgpack_packer* pk, size_t n); static int msgpack_pack_str(msgpack_packer* pk, size_t l); static int msgpack_pack_str_body(msgpack_packer* pk, const void* b, size_t l); +static int msgpack_pack_v4raw(msgpack_packer* pk, size_t l); +static int msgpack_pack_v4raw_body(msgpack_packer* pk, const void* b, size_t l); + static int msgpack_pack_bin(msgpack_packer* pk, size_t l); static int msgpack_pack_bin_body(msgpack_packer* pk, const void* b, size_t l); @@ -150,4 +153,3 @@ inline void msgpack_packer_free(msgpack_packer* pk) #endif #endif /* msgpack/pack.h */ - diff --git a/include/msgpack/pack.hpp b/include/msgpack/pack.hpp index 0520ef15..40d47513 100644 --- a/include/msgpack/pack.hpp +++ b/include/msgpack/pack.hpp @@ -88,6 +88,10 @@ public: packer& pack_str(uint32_t l); packer& pack_str_body(const char* b, uint32_t l); + // v4 + packer& pack_v4raw(uint32_t l); + packer& pack_v4raw_body(const char* b, uint32_t l); + packer& pack_bin(uint32_t l); packer& pack_bin_body(const char* b, uint32_t l); @@ -713,6 +717,34 @@ inline packer& packer::pack_str_body(const char* b, uint32_t l) return *this; } +// Raw (V4) + +template +inline packer& packer::pack_v4raw(uint32_t l) +{ + if(l < 32) { + unsigned char d = 0xa0u | static_cast(l); + char buf = take8_8(d); + append_buffer(&buf, 1); + } else if(l < 65536) { + char buf[3]; + buf[0] = static_cast(0xdau); _msgpack_store16(&buf[1], static_cast(l)); + append_buffer(buf, 3); + } else { + char buf[5]; + buf[0] = static_cast(0xdbu); _msgpack_store32(&buf[1], static_cast(l)); + append_buffer(buf, 5); + } + return *this; +} + +template +inline packer& packer::pack_v4raw_body(const char* b, uint32_t l) +{ + append_buffer(b, l); + return *this; +} + template inline packer& packer::pack_bin(uint32_t l) { diff --git a/include/msgpack/pack_template.h b/include/msgpack/pack_template.h index 4041d1ce..63e151d8 100644 --- a/include/msgpack/pack_template.h +++ b/include/msgpack/pack_template.h @@ -779,6 +779,31 @@ msgpack_pack_inline_func(_str_body)(msgpack_pack_user x, const void* b, size_t l msgpack_pack_append_buffer(x, (const unsigned char*)b, l); } +/* + * Raw (V4) + */ + +msgpack_pack_inline_func(_v4raw)(msgpack_pack_user x, size_t l) +{ + if(l < 32) { + unsigned char d = 0xa0 | (uint8_t)l; + msgpack_pack_append_buffer(x, &TAKE8_8(d), 1); + } else if(l < 65536) { + unsigned char buf[3]; + buf[0] = 0xda; _msgpack_store16(&buf[1], (uint16_t)l); + msgpack_pack_append_buffer(x, buf, 3); + } else { + unsigned char buf[5]; + buf[0] = 0xdb; _msgpack_store32(&buf[1], (uint32_t)l); + msgpack_pack_append_buffer(x, buf, 5); + } +} + +msgpack_pack_inline_func(_v4raw_body)(msgpack_pack_user x, const void* b, size_t l) +{ + msgpack_pack_append_buffer(x, (const unsigned char*)b, l); +} + /* * Bin */ @@ -888,4 +913,3 @@ msgpack_pack_inline_func(_ext_body)(msgpack_pack_user x, const void* b, size_t l #undef msgpack_pack_real_int16 #undef msgpack_pack_real_int32 #undef msgpack_pack_real_int64 - diff --git a/include/msgpack/type.hpp b/include/msgpack/type.hpp index 2300a0f4..22f06439 100644 --- a/include/msgpack/type.hpp +++ b/include/msgpack/type.hpp @@ -10,6 +10,7 @@ #include "adaptor/nil.hpp" #include "adaptor/pair.hpp" #include "adaptor/raw.hpp" +#include "adaptor/v4raw.hpp" #include "adaptor/set.hpp" #include "adaptor/string.hpp" #include "adaptor/vector.hpp" diff --git a/src/Makefile.am b/src/Makefile.am index b5dafe60..57160f4f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -81,6 +81,7 @@ nobase_include_HEADERS += \ ../include/msgpack/adaptor/nil.hpp \ ../include/msgpack/adaptor/pair.hpp \ ../include/msgpack/adaptor/raw.hpp \ + ../include/msgpack/adaptor/v4raw.hpp \ ../include/msgpack/adaptor/set.hpp \ ../include/msgpack/adaptor/string.hpp \ ../include/msgpack/adaptor/tr1/unordered_map.hpp \ diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 24e7befe..59628d5b 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -30,6 +30,7 @@ LIST (APPEND check_PROGRAMS reference.cpp limit.cpp json.cpp + raw.cpp ) IF (MSGPACK_BOOST) diff --git a/test/Makefile.am b/test/Makefile.am index 5a8a2872..b6913610 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -27,6 +27,7 @@ check_PROGRAMS = \ reference \ limit \ json \ + raw \ iterator_cpp11 \ boost_optional \ boost_string_ref @@ -82,6 +83,8 @@ limit_SOURCES = limit.cpp json_SOURCES = json.cpp +raw_SOURCES = raw.cpp + iterator_cpp11_SOURCES = iterator_cpp11.cpp boost_optional_SOURCES = boost_optional.cpp diff --git a/test/msgpack_c.cpp b/test/msgpack_c.cpp index 0f1bfb96..36f4fa10 100644 --- a/test/msgpack_c.cpp +++ b/test/msgpack_c.cpp @@ -753,6 +753,349 @@ TEST(MSGPACKC, simple_buffer_str) msgpack_sbuffer_destroy(&sbuf); } +TEST(MSGPACKC, simple_buffer_str_fix_l) +{ + char const* str = NULL; + unsigned int str_size = 0; + msgpack_sbuffer sbuf; + msgpack_sbuffer_init(&sbuf); + msgpack_packer pk; + msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write); + msgpack_pack_str(&pk, str_size); + msgpack_pack_str_body(&pk, str, str_size); + EXPECT_EQ(sbuf.size, 0x01); + EXPECT_EQ(sbuf.data[0], static_cast(0xa0u)); + + msgpack_zone z; + msgpack_zone_init(&z, 2048); + msgpack_object obj; + msgpack_unpack_return ret; + ret = msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj); + EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret); + EXPECT_EQ(MSGPACK_OBJECT_STR, obj.type); + EXPECT_EQ(str_size, obj.via.str.size); + EXPECT_EQ(0, memcmp(str, obj.via.str.ptr, str_size)); + + msgpack_zone_destroy(&z); + msgpack_sbuffer_destroy(&sbuf); +} + +TEST(MSGPACKC, simple_buffer_str_fix_h) +{ + char str[0x1f] = {'0'}; + unsigned int str_size = sizeof(str); + msgpack_sbuffer sbuf; + msgpack_sbuffer_init(&sbuf); + msgpack_packer pk; + msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write); + msgpack_pack_str(&pk, str_size); + msgpack_pack_str_body(&pk, str, str_size); + EXPECT_EQ(sbuf.size, 0x1f+1); + EXPECT_EQ(sbuf.data[0], static_cast(0xbfu)); + + msgpack_zone z; + msgpack_zone_init(&z, 2048); + msgpack_object obj; + msgpack_unpack_return ret; + ret = msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj); + EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret); + EXPECT_EQ(MSGPACK_OBJECT_STR, obj.type); + EXPECT_EQ(str_size, obj.via.str.size); + EXPECT_EQ(0, memcmp(str, obj.via.str.ptr, str_size)); + + msgpack_zone_destroy(&z); + msgpack_sbuffer_destroy(&sbuf); +} + +TEST(MSGPACKC, simple_buffer_str_8_l) +{ + char str[0x1f+1] = {'0'}; + unsigned int str_size = sizeof(str); + msgpack_sbuffer sbuf; + msgpack_sbuffer_init(&sbuf); + msgpack_packer pk; + msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write); + msgpack_pack_str(&pk, str_size); + msgpack_pack_str_body(&pk, str, str_size); + EXPECT_EQ(sbuf.size, 0x1f+1+2); + EXPECT_EQ(sbuf.data[0], static_cast(0xd9u)); + EXPECT_EQ(sbuf.data[1], static_cast(0x20u)); + + msgpack_zone z; + msgpack_zone_init(&z, 2048); + msgpack_object obj; + msgpack_unpack_return ret; + ret = msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj); + EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret); + EXPECT_EQ(MSGPACK_OBJECT_STR, obj.type); + EXPECT_EQ(str_size, obj.via.str.size); + EXPECT_EQ(0, memcmp(str, obj.via.str.ptr, str_size)); + + msgpack_zone_destroy(&z); + msgpack_sbuffer_destroy(&sbuf); +} + +TEST(MSGPACKC, simple_buffer_str_8_h) +{ + char str[0xff] = {'0'}; + unsigned int str_size = sizeof(str); + msgpack_sbuffer sbuf; + msgpack_sbuffer_init(&sbuf); + msgpack_packer pk; + msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write); + msgpack_pack_str(&pk, str_size); + msgpack_pack_str_body(&pk, str, str_size); + EXPECT_EQ(sbuf.size, 0xff+2); + EXPECT_EQ(sbuf.data[0], static_cast(0xd9u)); + EXPECT_EQ(sbuf.data[1], static_cast(0xffu)); + + msgpack_zone z; + msgpack_zone_init(&z, 2048); + msgpack_object obj; + msgpack_unpack_return ret; + ret = msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj); + EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret); + EXPECT_EQ(MSGPACK_OBJECT_STR, obj.type); + EXPECT_EQ(str_size, obj.via.str.size); + EXPECT_EQ(0, memcmp(str, obj.via.str.ptr, str_size)); + + msgpack_zone_destroy(&z); + msgpack_sbuffer_destroy(&sbuf); +} + +TEST(MSGPACKC, simple_buffer_str_16_l) +{ + char str[0xff+1] = {'0'}; + unsigned int str_size = sizeof(str); + msgpack_sbuffer sbuf; + msgpack_sbuffer_init(&sbuf); + msgpack_packer pk; + msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write); + msgpack_pack_str(&pk, str_size); + msgpack_pack_str_body(&pk, str, str_size); + EXPECT_EQ(sbuf.size, 0xff+1+3); + EXPECT_EQ(sbuf.data[0], static_cast(0xdau)); + EXPECT_EQ(sbuf.data[1], static_cast(0x01u)); + EXPECT_EQ(sbuf.data[2], static_cast(0x00u)); + + msgpack_zone z; + msgpack_zone_init(&z, 2048); + msgpack_object obj; + msgpack_unpack_return ret; + ret = msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj); + EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret); + EXPECT_EQ(MSGPACK_OBJECT_STR, obj.type); + EXPECT_EQ(str_size, obj.via.str.size); + EXPECT_EQ(0, memcmp(str, obj.via.str.ptr, str_size)); + + msgpack_zone_destroy(&z); + msgpack_sbuffer_destroy(&sbuf); +} + +TEST(MSGPACKC, simple_buffer_str_16_h) +{ + char str[0xffff] = {'0'}; + unsigned int str_size = sizeof(str); + msgpack_sbuffer sbuf; + msgpack_sbuffer_init(&sbuf); + msgpack_packer pk; + msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write); + msgpack_pack_str(&pk, str_size); + msgpack_pack_str_body(&pk, str, str_size); + EXPECT_EQ(sbuf.size, 0xffff+3); + EXPECT_EQ(sbuf.data[0], static_cast(0xdau)); + EXPECT_EQ(sbuf.data[1], static_cast(0xffu)); + EXPECT_EQ(sbuf.data[2], static_cast(0xffu)); + + msgpack_zone z; + msgpack_zone_init(&z, 2048); + msgpack_object obj; + msgpack_unpack_return ret; + ret = msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj); + EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret); + EXPECT_EQ(MSGPACK_OBJECT_STR, obj.type); + EXPECT_EQ(str_size, obj.via.str.size); + EXPECT_EQ(0, memcmp(str, obj.via.str.ptr, str_size)); + + msgpack_zone_destroy(&z); + msgpack_sbuffer_destroy(&sbuf); +} + +TEST(MSGPACKC, simple_buffer_str_32_l) +{ + char str[0xffff+1] = {'0'}; + unsigned int str_size = sizeof(str); + msgpack_sbuffer sbuf; + msgpack_sbuffer_init(&sbuf); + msgpack_packer pk; + msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write); + msgpack_pack_str(&pk, str_size); + msgpack_pack_str_body(&pk, str, str_size); + EXPECT_EQ(sbuf.size, 0xffff+1+5); + EXPECT_EQ(sbuf.data[0], static_cast(0xdbu)); + EXPECT_EQ(sbuf.data[1], static_cast(0x00u)); + EXPECT_EQ(sbuf.data[2], static_cast(0x01u)); + EXPECT_EQ(sbuf.data[3], static_cast(0x00u)); + EXPECT_EQ(sbuf.data[4], static_cast(0x00u)); + + msgpack_zone z; + msgpack_zone_init(&z, 2048); + msgpack_object obj; + msgpack_unpack_return ret; + ret = msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj); + EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret); + EXPECT_EQ(MSGPACK_OBJECT_STR, obj.type); + EXPECT_EQ(str_size, obj.via.str.size); + EXPECT_EQ(0, memcmp(str, obj.via.str.ptr, str_size)); + + msgpack_zone_destroy(&z); + msgpack_sbuffer_destroy(&sbuf); +} + +TEST(MSGPACKC, simple_buffer_v4raw_fix_l) +{ + char const* str = NULL; + unsigned int str_size = 0; + msgpack_sbuffer sbuf; + msgpack_sbuffer_init(&sbuf); + msgpack_packer pk; + msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write); + msgpack_pack_v4raw(&pk, str_size); + msgpack_pack_v4raw_body(&pk, str, str_size); + EXPECT_EQ(sbuf.size, 0x01); + EXPECT_EQ(sbuf.data[0], static_cast(0xa0u)); + + msgpack_zone z; + msgpack_zone_init(&z, 2048); + msgpack_object obj; + msgpack_unpack_return ret; + ret = msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj); + EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret); + EXPECT_EQ(MSGPACK_OBJECT_STR, obj.type); + EXPECT_EQ(str_size, obj.via.str.size); + EXPECT_EQ(0, memcmp(str, obj.via.str.ptr, str_size)); + + msgpack_zone_destroy(&z); + msgpack_sbuffer_destroy(&sbuf); +} + +TEST(MSGPACKC, simple_buffer_v4raw_fix_h) +{ + char str[0x1f] = {'0'}; + unsigned int str_size = sizeof(str); + msgpack_sbuffer sbuf; + msgpack_sbuffer_init(&sbuf); + msgpack_packer pk; + msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write); + msgpack_pack_v4raw(&pk, str_size); + msgpack_pack_v4raw_body(&pk, str, str_size); + EXPECT_EQ(sbuf.size, 0x1f+1); + EXPECT_EQ(sbuf.data[0], static_cast(0xbfu)); + + msgpack_zone z; + msgpack_zone_init(&z, 2048); + msgpack_object obj; + msgpack_unpack_return ret; + ret = msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj); + EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret); + EXPECT_EQ(MSGPACK_OBJECT_STR, obj.type); + EXPECT_EQ(str_size, obj.via.str.size); + EXPECT_EQ(0, memcmp(str, obj.via.str.ptr, str_size)); + + msgpack_zone_destroy(&z); + msgpack_sbuffer_destroy(&sbuf); +} + +TEST(MSGPACKC, simple_buffer_v4raw_16_l) +{ + char str[0x1f+1] = {'0'}; + unsigned int str_size = sizeof(str); + msgpack_sbuffer sbuf; + msgpack_sbuffer_init(&sbuf); + msgpack_packer pk; + msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write); + msgpack_pack_v4raw(&pk, str_size); + msgpack_pack_v4raw_body(&pk, str, str_size); + EXPECT_EQ(sbuf.size, 0x1f+1+3); + EXPECT_EQ(sbuf.data[0], static_cast(0xdau)); + EXPECT_EQ(sbuf.data[1], static_cast(0x00u)); + EXPECT_EQ(sbuf.data[2], static_cast(0x20u)); + + msgpack_zone z; + msgpack_zone_init(&z, 2048); + msgpack_object obj; + msgpack_unpack_return ret; + ret = msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj); + EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret); + EXPECT_EQ(MSGPACK_OBJECT_STR, obj.type); + EXPECT_EQ(str_size, obj.via.str.size); + EXPECT_EQ(0, memcmp(str, obj.via.str.ptr, str_size)); + + msgpack_zone_destroy(&z); + msgpack_sbuffer_destroy(&sbuf); +} + +TEST(MSGPACKC, simple_buffer_v4raw_16_h) +{ + char str[0xffff] = {'0'}; + unsigned int str_size = sizeof(str); + msgpack_sbuffer sbuf; + msgpack_sbuffer_init(&sbuf); + msgpack_packer pk; + msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write); + msgpack_pack_v4raw(&pk, str_size); + msgpack_pack_v4raw_body(&pk, str, str_size); + EXPECT_EQ(sbuf.size, 0xffff+3); + EXPECT_EQ(sbuf.data[0], static_cast(0xdau)); + EXPECT_EQ(sbuf.data[1], static_cast(0xffu)); + EXPECT_EQ(sbuf.data[2], static_cast(0xffu)); + + msgpack_zone z; + msgpack_zone_init(&z, 2048); + msgpack_object obj; + msgpack_unpack_return ret; + ret = msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj); + EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret); + EXPECT_EQ(MSGPACK_OBJECT_STR, obj.type); + EXPECT_EQ(str_size, obj.via.str.size); + EXPECT_EQ(0, memcmp(str, obj.via.str.ptr, str_size)); + + msgpack_zone_destroy(&z); + msgpack_sbuffer_destroy(&sbuf); +} + +TEST(MSGPACKC, simple_buffer_v4raw_32_l) +{ + char str[0xffff+1] = {'0'}; + unsigned int str_size = sizeof(str); + msgpack_sbuffer sbuf; + msgpack_sbuffer_init(&sbuf); + msgpack_packer pk; + msgpack_packer_init(&pk, &sbuf, msgpack_sbuffer_write); + msgpack_pack_v4raw(&pk, str_size); + msgpack_pack_v4raw_body(&pk, str, str_size); + EXPECT_EQ(sbuf.size, 0xffff+1+5); + EXPECT_EQ(sbuf.data[0], static_cast(0xdbu)); + EXPECT_EQ(sbuf.data[1], static_cast(0x00u)); + EXPECT_EQ(sbuf.data[2], static_cast(0x01u)); + EXPECT_EQ(sbuf.data[3], static_cast(0x00u)); + EXPECT_EQ(sbuf.data[4], static_cast(0x00u)); + + msgpack_zone z; + msgpack_zone_init(&z, 2048); + msgpack_object obj; + msgpack_unpack_return ret; + ret = msgpack_unpack(sbuf.data, sbuf.size, NULL, &z, &obj); + EXPECT_EQ(MSGPACK_UNPACK_SUCCESS, ret); + EXPECT_EQ(MSGPACK_OBJECT_STR, obj.type); + EXPECT_EQ(str_size, obj.via.str.size); + EXPECT_EQ(0, memcmp(str, obj.via.str.ptr, str_size)); + + msgpack_zone_destroy(&z); + msgpack_sbuffer_destroy(&sbuf); +} + + TEST(MSGPACKC, unpack_fixstr) { size_t str_size = 7; diff --git a/test/raw.cpp b/test/raw.cpp new file mode 100644 index 00000000..8c961fe4 --- /dev/null +++ b/test/raw.cpp @@ -0,0 +1,235 @@ +#include + +#include +#include + +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +TEST(MSGPACK_RAW_REF, pack_unpack) +{ + std::string s = "ABC"; + + msgpack::type::raw_ref rr1(s.data(), s.size()); + std::stringstream ss; + msgpack::pack(ss, rr1); + std::string packed_str = ss.str(); + EXPECT_EQ(packed_str[0], static_cast(0xc4u)); + EXPECT_EQ(packed_str[1], static_cast(0x03u)); + EXPECT_EQ(packed_str[2], 'A'); + EXPECT_EQ(packed_str[3], 'B'); + EXPECT_EQ(packed_str[4], 'C'); + + msgpack::unpacked upd; + msgpack::unpack(upd, ss.str().data(), ss.str().size()); + msgpack::type::raw_ref rr2 = upd.get().as(); + EXPECT_EQ(rr1, rr2); +} + +TEST(MSGPACK_RAW_REF, pack_unpack_8_l) +{ + std::string s; + + msgpack::type::raw_ref rr1(s.data(), s.size()); + std::stringstream ss; + msgpack::pack(ss, rr1); + std::string packed_str = ss.str(); + EXPECT_EQ(packed_str[0], static_cast(0xc4u)); + EXPECT_EQ(packed_str[1], static_cast(0x00u)); + + msgpack::unpacked upd; + msgpack::unpack(upd, ss.str().data(), ss.str().size()); + msgpack::type::raw_ref rr2 = upd.get().as(); + EXPECT_EQ(rr1, rr2); +} + +TEST(MSGPACK_RAW_REF, pack_unpack_8_h) +{ + std::string s(0xff, 'A'); + + msgpack::type::raw_ref rr1(s.data(), s.size()); + std::stringstream ss; + msgpack::pack(ss, rr1); + std::string packed_str = ss.str(); + EXPECT_EQ(packed_str[0], static_cast(0xc4u)); + EXPECT_EQ(packed_str[1], static_cast(0xffu)); + EXPECT_EQ(packed_str[2], 'A'); + + msgpack::unpacked upd; + msgpack::unpack(upd, ss.str().data(), ss.str().size()); + msgpack::type::raw_ref rr2 = upd.get().as(); + EXPECT_EQ(rr1, rr2); +} + +TEST(MSGPACK_RAW_REF, pack_unpack_16_l) +{ + std::string s(0xff+1, 'A'); + + msgpack::type::raw_ref rr1(s.data(), s.size()); + std::stringstream ss; + msgpack::pack(ss, rr1); + std::string packed_str = ss.str(); + EXPECT_EQ(packed_str[0], static_cast(0xc5u)); + EXPECT_EQ(packed_str[1], static_cast(0x01)); + EXPECT_EQ(packed_str[2], static_cast(0x00)); + EXPECT_EQ(packed_str[3], 'A'); + + msgpack::unpacked upd; + msgpack::unpack(upd, ss.str().data(), ss.str().size()); + msgpack::type::raw_ref rr2 = upd.get().as(); + EXPECT_EQ(rr1, rr2); +} + +TEST(MSGPACK_RAW_REF, pack_unpack_16_h) +{ + std::string s(0xffff, 'A'); + + msgpack::type::raw_ref rr1(s.data(), s.size()); + std::stringstream ss; + msgpack::pack(ss, rr1); + std::string packed_str = ss.str(); + EXPECT_EQ(packed_str[0], static_cast(0xc5u)); + EXPECT_EQ(packed_str[1], static_cast(0xff)); + EXPECT_EQ(packed_str[2], static_cast(0xff)); + EXPECT_EQ(packed_str[3], 'A'); + + msgpack::unpacked upd; + msgpack::unpack(upd, ss.str().data(), ss.str().size()); + msgpack::type::raw_ref rr2 = upd.get().as(); + EXPECT_EQ(rr1, rr2); +} + +TEST(MSGPACK_RAW_REF, pack_unpack_32_l) +{ + std::string s(0xffff+1, 'A'); + + msgpack::type::raw_ref rr1(s.data(), s.size()); + std::stringstream ss; + msgpack::pack(ss, rr1); + std::string packed_str = ss.str(); + EXPECT_EQ(packed_str[0], static_cast(0xc6u)); + EXPECT_EQ(packed_str[1], static_cast(0x00)); + EXPECT_EQ(packed_str[2], static_cast(0x01)); + EXPECT_EQ(packed_str[3], static_cast(0x00)); + EXPECT_EQ(packed_str[4], static_cast(0x00)); + EXPECT_EQ(packed_str[5], 'A'); + + msgpack::unpacked upd; + msgpack::unpack(upd, ss.str().data(), ss.str().size()); + msgpack::type::raw_ref rr2 = upd.get().as(); + EXPECT_EQ(rr1, rr2); +} + +TEST(MSGPACK_V4RAW_REF, pack_unpack) +{ + std::string s = "ABC"; + + msgpack::type::v4raw_ref rr1(s.data(), s.size()); + std::stringstream ss; + msgpack::pack(ss, rr1); + std::string packed_str = ss.str(); + EXPECT_EQ(packed_str[0], static_cast(0xa3u)); + EXPECT_EQ(packed_str[1], 'A'); + EXPECT_EQ(packed_str[2], 'B'); + EXPECT_EQ(packed_str[3], 'C'); + + msgpack::unpacked upd; + msgpack::unpack(upd, ss.str().data(), ss.str().size()); + msgpack::type::v4raw_ref rr2 = upd.get().as(); + EXPECT_EQ(rr1, rr2); +} + +TEST(MSGPACK_V4RAW_REF, pack_unpack_fix_l) +{ + std::string s; + + msgpack::type::v4raw_ref rr1(s.data(), s.size()); + std::stringstream ss; + msgpack::pack(ss, rr1); + std::string packed_str = ss.str(); + EXPECT_EQ(packed_str[0], static_cast(0xa0u)); + + msgpack::unpacked upd; + msgpack::unpack(upd, ss.str().data(), ss.str().size()); + msgpack::type::v4raw_ref rr2 = upd.get().as(); + EXPECT_EQ(rr1, rr2); +} + +TEST(MSGPACK_V4RAW_REF, pack_unpack_fix_h) +{ + std::string s(0x1f, 'A'); + + msgpack::type::v4raw_ref rr1(s.data(), s.size()); + std::stringstream ss; + msgpack::pack(ss, rr1); + std::string packed_str = ss.str(); + EXPECT_EQ(packed_str[0], static_cast(0xbfu)); + EXPECT_EQ(packed_str[1], 'A'); + + msgpack::unpacked upd; + msgpack::unpack(upd, ss.str().data(), ss.str().size()); + msgpack::type::v4raw_ref rr2 = upd.get().as(); + EXPECT_EQ(rr1, rr2); +} + +TEST(MSGPACK_V4RAW_REF, pack_unpack_16_l) +{ + std::string s(0x1f+1, 'A'); + + msgpack::type::v4raw_ref rr1(s.data(), s.size()); + std::stringstream ss; + msgpack::pack(ss, rr1); + std::string packed_str = ss.str(); + EXPECT_EQ(packed_str[0], static_cast(0xdau)); + EXPECT_EQ(packed_str[1], static_cast(0x00u)); + EXPECT_EQ(packed_str[2], static_cast(0x20u)); + EXPECT_EQ(packed_str[3], 'A'); + + msgpack::unpacked upd; + msgpack::unpack(upd, ss.str().data(), ss.str().size()); + msgpack::type::v4raw_ref rr2 = upd.get().as(); + EXPECT_EQ(rr1, rr2); +} + +TEST(MSGPACK_V4RAW_REF, pack_unpack_16_h) +{ + std::string s(0xffff, 'A'); + + msgpack::type::v4raw_ref rr1(s.data(), s.size()); + std::stringstream ss; + msgpack::pack(ss, rr1); + std::string packed_str = ss.str(); + EXPECT_EQ(packed_str[0], static_cast(0xdau)); + EXPECT_EQ(packed_str[1], static_cast(0xffu)); + EXPECT_EQ(packed_str[2], static_cast(0xffu)); + EXPECT_EQ(packed_str[3], 'A'); + + msgpack::unpacked upd; + msgpack::unpack(upd, ss.str().data(), ss.str().size()); + msgpack::type::v4raw_ref rr2 = upd.get().as(); + EXPECT_EQ(rr1, rr2); +} + +TEST(MSGPACK_V4RAW_REF, pack_unpack_32_l) +{ + std::string s(0xffff+1, 'A'); + + msgpack::type::v4raw_ref rr1(s.data(), s.size()); + std::stringstream ss; + msgpack::pack(ss, rr1); + std::string packed_str = ss.str(); + EXPECT_EQ(packed_str[0], static_cast(0xdbu)); + EXPECT_EQ(packed_str[1], static_cast(0x00)); + EXPECT_EQ(packed_str[2], static_cast(0x01)); + EXPECT_EQ(packed_str[3], static_cast(0x00)); + EXPECT_EQ(packed_str[4], static_cast(0x00)); + EXPECT_EQ(packed_str[5], 'A'); + + msgpack::unpacked upd; + msgpack::unpack(upd, ss.str().data(), ss.str().size()); + msgpack::type::v4raw_ref rr2 = upd.get().as(); + EXPECT_EQ(rr1, rr2); +}