diff --git a/CMakeLists.txt b/CMakeLists.txt index 0b91fb7d..3bd4e18a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -164,6 +164,7 @@ IF (MSGPACK_ENABLE_CXX) LIST (APPEND msgpack_HEADERS include/msgpack.hpp include/msgpack/adaptor/adaptor_base.hpp + include/msgpack/adaptor/array_ref.hpp include/msgpack/adaptor/bool.hpp include/msgpack/adaptor/boost/fusion.hpp include/msgpack/adaptor/boost/optional.hpp diff --git a/include/msgpack/adaptor/array_ref.hpp b/include/msgpack/adaptor/array_ref.hpp new file mode 100644 index 00000000..387b6cf1 --- /dev/null +++ b/include/msgpack/adaptor/array_ref.hpp @@ -0,0 +1,182 @@ +// +// MessagePack for C++ static resolution routine +// +// Copyright (C) 2008-2009 FURUHASHI Sadayuki +// +// 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_ARRAY_REF_HPP +#define MSGPACK_TYPE_ARRAY_REF_HPP + +#include "msgpack/versioning.hpp" +#include "msgpack/adaptor/adaptor_base.hpp" +#include "msgpack/adaptor/check_container_size.hpp" +#include +#include + +namespace msgpack { + +/// @cond +MSGPACK_API_VERSION_NAMESPACE(v1) { +/// @endcond + +namespace type { + +template +struct array_ref { + array_ref() : data(nullptr) {} + array_ref(T& t) : data(&t) {} + + T* data; + + template + bool operator==(array_ref const& t) const { + return *data == *t.data; + } + template + bool operator!=(array_ref const& t) const { + return !(*data == *t.data); + } + template + bool operator< (array_ref const& t) const + { + return *data < *t.data; + } + template + bool operator> (array_ref const& t) const + { + return *t.data < *data; + } + template + bool operator<= (array_ref const& t) const + { + return !(*t.data < *data); + } + template + bool operator>= (array_ref const& t) const + { + return !(*data < *t.data); + } +}; + +template +inline array_ref make_array_ref(T const& t) { + return array_ref(t); +} + +template +inline array_ref make_array_ref(T& t) { + return array_ref(t); +} + + +} // namespace type + +namespace adaptor { + +template +struct convert > { + msgpack::object const& operator()(msgpack::object const& o, msgpack::type::array_ref& v) const { + if (!v.data) { throw msgpack::type_error(); } + if (o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); } + if (v.data->size() < o.via.bin.size) { throw msgpack::type_error(); } + if (o.via.array.size > 0) { + msgpack::object* p = o.via.array.ptr; + msgpack::object* const pend = o.via.array.ptr + o.via.array.size; + typename T::iterator it = v.data->begin(); + do { + p->convert(*it); + ++p; + ++it; + } while(p < pend); + } + return o; + } +}; + +template +struct convert > > { + msgpack::object const& operator()(msgpack::object const& o, msgpack::type::array_ref >& v) const { + if (!v.data) { throw msgpack::type_error(); } + if (o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); } + v.data->resize(o.via.bin.size); + if (o.via.array.size > 0) { + msgpack::object* p = o.via.array.ptr; + msgpack::object* const pend = o.via.array.ptr + o.via.array.size; + typename std::vector::iterator it = v.data->begin(); + do { + p->convert(*it); + ++p; + ++it; + } while(p < pend); + } + return o; + } +}; + +template +struct pack > { + template + msgpack::packer& operator()(msgpack::packer& o, const msgpack::type::array_ref& v) const { + if (!v.data) { throw msgpack::type_error(); } + uint32_t size = checked_get_container_size(v.data->size()); + o.pack_array(size); + for (typename T::const_iterator it(v.data->begin()), it_end(v.data->end()); + it != it_end; ++it) { + o.pack(*it); + } + return o; + } +}; + +template +struct object_with_zone > { + void operator()(msgpack::object::with_zone& o, const msgpack::type::array_ref& v) const { + if (!v.data) { throw msgpack::type_error(); } + o.type = msgpack::type::ARRAY; + if (v.data->empty()) { + o.via.array.ptr = nullptr; + o.via.array.size = 0; + } + else { + uint32_t size = checked_get_container_size(v.data->size()); + msgpack::object* p = static_cast(o.zone.allocate_align(sizeof(msgpack::object)*size)); + msgpack::object* const pend = p + size; + o.via.array.ptr = p; + o.via.array.size = size; + typename T::const_iterator it(v.data->begin()); + do { +#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && !defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif // (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && !defined(__clang__) + *p = msgpack::object(*it, o.zone); +#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && !defined(__clang__) +#pragma GCC diagnostic pop +#endif // (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && !defined(__clang__) + ++p; + ++it; + } while(p < pend); + } + } +}; + +} // namespace adaptor + +/// @cond +} // MSGPACK_API_VERSION_NAMESPACE(v1) +/// @endcond + +} // namespace msgpack + +#endif // MSGPACK_TYPE_ARRAY_REF_HPP diff --git a/include/msgpack/adaptor/cpp11/array_unsigned_char.hpp b/include/msgpack/adaptor/cpp11/array_unsigned_char.hpp new file mode 100644 index 00000000..879b7e67 --- /dev/null +++ b/include/msgpack/adaptor/cpp11/array_unsigned_char.hpp @@ -0,0 +1,97 @@ +// +// MessagePack for C++ static resolution routine +// +// Copyright (C) 2014-2015 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_ARRAY_UNSIGNED_CHAR_HPP +#define MSGPACK_TYPE_ARRAY_UNSIGNED_CHAR_HPP + +#include "msgpack/versioning.hpp" +#include "msgpack/adaptor/adaptor_base.hpp" +#include "msgpack/adaptor/check_container_size.hpp" + +#include + +namespace msgpack { + +/// @cond +MSGPACK_API_VERSION_NAMESPACE(v1) { +/// @endcond + +namespace adaptor { + +template +struct convert> { + msgpack::object const& operator()(msgpack::object const& o, std::array& v) const { + switch (o.type) { + case msgpack::type::BIN: + if(o.via.bin.size != N) { throw msgpack::type_error(); } + std::memcpy(v.data(), 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.data(), o.via.str.ptr, N); + break; + default: + throw msgpack::type_error(); + break; + } + return o; + } +}; + +template +struct pack> { + template + msgpack::packer& operator()(msgpack::packer& o, const std::array& v) const { + uint32_t size = checked_get_container_size(v.size()); + o.pack_bin(size); + o.pack_bin_body(reinterpret_cast(v.data()), size); + + return o; + } +}; + +template +struct object> { + void operator()(msgpack::object& o, const std::array& v) const { + uint32_t size = checked_get_container_size(v.size()); + o.type = msgpack::type::BIN; + o.via.bin.ptr = reinterpret_cast(v.data()); + o.via.bin.size = size; + } +}; + +template +struct object_with_zone> { + void operator()(msgpack::object::with_zone& o, const std::array& v) const { + uint32_t size = checked_get_container_size(v.size()); + o.type = msgpack::type::BIN; + char* ptr = static_cast(o.zone.allocate_align(size)); + o.via.bin.ptr = ptr; + o.via.bin.size = size; + std::memcpy(ptr, v.data(), size); + } +}; + +} // namespace adaptor + +/// @cond +} // MSGPACK_API_VERSION_NAMESPACE(v1) +/// @endcond + +} // namespace msgpack + +#endif // MSGPACK_TYPE_ARRAY_UNSIGNED_CHAR_HPP diff --git a/include/msgpack/adaptor/vector_unsigned_char.hpp b/include/msgpack/adaptor/vector_unsigned_char.hpp new file mode 100644 index 00000000..dedbebcb --- /dev/null +++ b/include/msgpack/adaptor/vector_unsigned_char.hpp @@ -0,0 +1,97 @@ +// +// MessagePack for C++ static resolution routine +// +// Copyright (C) 2014-2015 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_VECTOR_UNSIGNED_CHAR_HPP +#define MSGPACK_TYPE_VECTOR_UNSIGNED_CHAR_HPP + +#include "msgpack/versioning.hpp" +#include "msgpack/adaptor/adaptor_base.hpp" +#include "msgpack/adaptor/check_container_size.hpp" + +#include + +namespace msgpack { + +/// @cond +MSGPACK_API_VERSION_NAMESPACE(v1) { +/// @endcond + +namespace adaptor { + +template +struct convert > { + msgpack::object const& operator()(msgpack::object const& o, std::vector& v) const { + switch (o.type) { + case msgpack::type::BIN: + v.resize(o.via.bin.size); + std::memcpy(&v.front(), o.via.bin.ptr, o.via.bin.size); + break; + case msgpack::type::STR: + v.resize(o.via.str.size); + std::memcpy(&v.front(), o.via.str.ptr, o.via.str.size); + break; + default: + throw msgpack::type_error(); + break; + } + return o; + } +}; + +template +struct pack > { + template + msgpack::packer& operator()(msgpack::packer& o, const std::vector& v) const { + uint32_t size = checked_get_container_size(v.size()); + o.pack_bin(size); + o.pack_bin_body(reinterpret_cast(&v.front()), size); + + return o; + } +}; + +template +struct object > { + void operator()(msgpack::object& o, const std::vector& v) const { + uint32_t size = checked_get_container_size(v.size()); + o.type = msgpack::type::BIN; + o.via.bin.ptr = reinterpret_cast(&v.front()); + o.via.bin.size = size; + } +}; + +template +struct object_with_zone > { + void operator()(msgpack::object::with_zone& o, const std::vector& v) const { + uint32_t size = checked_get_container_size(v.size()); + o.type = msgpack::type::BIN; + char* ptr = static_cast(o.zone.allocate_align(size)); + o.via.bin.ptr = ptr; + o.via.bin.size = size; + std::memcpy(ptr, &v.front(), size); + } +}; + +} // namespace adaptor + +/// @cond +} // MSGPACK_API_VERSION_NAMESPACE(v1) +/// @endcond + +} // namespace msgpack + +#endif // MSGPACK_TYPE_VECTOR_UNSIGNED_CHAR_HPP diff --git a/include/msgpack/cpp_config.hpp b/include/msgpack/cpp_config.hpp index 33396873..910d46e5 100644 --- a/include/msgpack/cpp_config.hpp +++ b/include/msgpack/cpp_config.hpp @@ -78,6 +78,22 @@ template struct enable_if { }; +template +struct integral_constant { + static T const value = val; + typedef T value_type; + typedef integral_constant type; +}; + +typedef integral_constant true_type; +typedef integral_constant false_type; + +template +struct is_same : false_type {}; + +template +struct is_same : true_type {}; + /// @cond } // MSGPACK_API_VERSION_NAMESPACE(v1) /// @endcond @@ -104,6 +120,7 @@ MSGPACK_API_VERSION_NAMESPACE(v1) { using std::move; using std::swap; using std::enable_if; + using std::is_same; /// @cond } // MSGPACK_API_VERSION_NAMESPACE(v1) diff --git a/include/msgpack/type.hpp b/include/msgpack/type.hpp index 4619fe0f..a888d6a9 100644 --- a/include/msgpack/type.hpp +++ b/include/msgpack/type.hpp @@ -1,4 +1,5 @@ #include "cpp_config.hpp" +#include "adaptor/array_ref.hpp" #include "adaptor/bool.hpp" #include "adaptor/char_ptr.hpp" #include "adaptor/deque.hpp" @@ -17,6 +18,7 @@ #include "adaptor/vector.hpp" #include "adaptor/vector_bool.hpp" #include "adaptor/vector_char.hpp" +#include "adaptor/vector_unsigned_char.hpp" #include "adaptor/msgpack_tuple.hpp" #include "adaptor/define.hpp" @@ -29,6 +31,7 @@ #include "adaptor/cpp11/array.hpp" #include "adaptor/cpp11/array_char.hpp" +#include "adaptor/cpp11/array_unsigned_char.hpp" #include "adaptor/cpp11/forward_list.hpp" #include "adaptor/cpp11/shared_ptr.hpp" #include "adaptor/cpp11/tuple.hpp" diff --git a/src/Makefile.am b/src/Makefile.am index b15c31a0..4043d766 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -173,6 +173,7 @@ if ENABLE_CXX nobase_include_HEADERS += \ ../include/msgpack.hpp \ ../include/msgpack/adaptor/adaptor_base.hpp \ + ../include/msgpack/adaptor/array_ref.hpp \ ../include/msgpack/adaptor/bool.hpp \ ../include/msgpack/adaptor/boost/fusion.hpp \ ../include/msgpack/adaptor/boost/optional.hpp \ diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index f0888588..4c9ab449 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -8,6 +8,7 @@ INCLUDE_DIRECTORIES ( ) LIST (APPEND check_PROGRAMS + array_ref.cpp buffer.cpp cases.cpp convert.cpp diff --git a/test/Makefile.am b/test/Makefile.am index 165a5e28..5863e1ac 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -3,6 +3,7 @@ AM_C_CPPFLAGS = -I$(top_srcdir)/include -pthread AM_LDFLAGS = $(top_builddir)/src/libmsgpack.la -lgtest_main -lgtest -lpthread check_PROGRAMS = \ + array_ref \ buffer \ cases \ convert \ @@ -45,6 +46,7 @@ check_PROGRAMS += \ TESTS = $(check_PROGRAMS) +array_ref_SOURCES = array_ref.cpp buffer_SOURCES = buffer.cpp cases_SOURCES = cases.cpp convert_SOURCES = convert.cpp diff --git a/test/array_ref.cpp b/test/array_ref.cpp new file mode 100644 index 00000000..968bb8e6 --- /dev/null +++ b/test/array_ref.cpp @@ -0,0 +1,310 @@ +#include + +#include +#include + +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +TEST(MSGPACK_ARRAY_REF, pack_unpack_convert_vector_char) +{ + std::vector v; + v.push_back('a'); + v.push_back('b'); + v.push_back('c'); + + msgpack::type::array_ref > ar1 = msgpack::type::make_array_ref(v); + std::stringstream ss; + msgpack::pack(ss, ar1); + + msgpack::unpacked upd; + msgpack::unpack(upd, ss.str().data(), ss.str().size()); + EXPECT_EQ(upd.get().type, msgpack::type::ARRAY); + std::vector v2; + msgpack::type::array_ref > ar2(v2); + upd.get().convert(ar2); + EXPECT_EQ(ar1, ar2); +} + +TEST(MSGPACK_ARRAY_REF, pack_unpack_convert_vector_char_const) +{ + std::vector v; + v.push_back('a'); + v.push_back('b'); + v.push_back('c'); + + std::vector const& cv = v; + + msgpack::type::array_ref const> ar1 = msgpack::type::make_array_ref(cv); + std::stringstream ss; + msgpack::pack(ss, ar1); + + msgpack::unpacked upd; + msgpack::unpack(upd, ss.str().data(), ss.str().size()); + EXPECT_EQ(upd.get().type, msgpack::type::ARRAY); + std::vector v2; + msgpack::type::array_ref > ar2(v2); + upd.get().convert(ar2); + EXPECT_EQ(ar1, ar2); +} + +TEST(MSGPACK_ARRAY_REF, pack_unpack_convert_vector_unsigned_char) +{ + std::vector v; + v.push_back('a'); + v.push_back('b'); + v.push_back('c'); + + msgpack::type::array_ref > ar1 = msgpack::type::make_array_ref(v); + std::stringstream ss; + msgpack::pack(ss, ar1); + + msgpack::unpacked upd; + msgpack::unpack(upd, ss.str().data(), ss.str().size()); + EXPECT_EQ(upd.get().type, msgpack::type::ARRAY); + std::vector v2; + msgpack::type::array_ref > ar2(v2); + upd.get().convert(ar2); + EXPECT_EQ(ar1, ar2); +} + +TEST(MSGPACK_ARRAY_REF, pack_unpack_convert_vector_unsigned_char_const) +{ + std::vector v; + v.push_back('a'); + v.push_back('b'); + v.push_back('c'); + + std::vector const& cv = v; + + msgpack::type::array_ref const> ar1 = msgpack::type::make_array_ref(cv); + std::stringstream ss; + msgpack::pack(ss, ar1); + + msgpack::unpacked upd; + msgpack::unpack(upd, ss.str().data(), ss.str().size()); + EXPECT_EQ(upd.get().type, msgpack::type::ARRAY); + std::vector v2; + msgpack::type::array_ref > ar2(v2); + upd.get().convert(ar2); + EXPECT_EQ(ar1, ar2); +} + +TEST(MSGPACK_ARRAY_REF, object_with_zone_vector_char) +{ + std::vector v; + v.push_back('a'); + v.push_back('b'); + v.push_back('c'); + + msgpack::type::array_ref > ar1 = msgpack::type::make_array_ref(v); + msgpack::zone z; + msgpack::object obj(ar1, z); + + EXPECT_EQ(obj.type, msgpack::type::ARRAY); + std::vector v2; + msgpack::type::array_ref > ar2(v2); + obj.convert(ar2); + EXPECT_EQ(ar1, ar2); +} + +TEST(MSGPACK_ARRAY_REF, object_with_zone_vector_char_const) +{ + std::vector v; + v.push_back('a'); + v.push_back('b'); + v.push_back('c'); + + std::vector const& cv = v; + + msgpack::type::array_ref const> ar1 = msgpack::type::make_array_ref(cv); + msgpack::zone z; + msgpack::object obj(ar1, z); + + EXPECT_EQ(obj.type, msgpack::type::ARRAY); + std::vector v2; + msgpack::type::array_ref > ar2(v2); + obj.convert(ar2); + EXPECT_EQ(ar1, ar2); +} + +TEST(MSGPACK_ARRAY_REF, object_with_zone_vector_unsigned_char) +{ + std::vector v; + v.push_back('a'); + v.push_back('b'); + v.push_back('c'); + + msgpack::type::array_ref > ar1 = msgpack::type::make_array_ref(v); + msgpack::zone z; + msgpack::object obj(ar1, z); + + EXPECT_EQ(obj.type, msgpack::type::ARRAY); + std::vector v2; + msgpack::type::array_ref > ar2(v2); + obj.convert(ar2); + EXPECT_EQ(ar1, ar2); +} + +TEST(MSGPACK_ARRAY_REF, object_with_zone_vector_unsigned_char_const) +{ + std::vector v; + v.push_back('a'); + v.push_back('b'); + v.push_back('c'); + + std::vector const& cv = v; + + msgpack::type::array_ref const> ar1 = msgpack::type::make_array_ref(cv); + msgpack::zone z; + msgpack::object obj(ar1, z); + + EXPECT_EQ(obj.type, msgpack::type::ARRAY); + std::vector v2; + msgpack::type::array_ref > ar2(v2); + obj.convert(ar2); + EXPECT_EQ(ar1, ar2); +} + +#if !defined(MSGPACK_USE_CPP03) + +TEST(MSGPACK_ARRAY_REF, pack_unpack_convert_array_char) +{ + std::array v { { 'a', 'b', 'c' } }; + + msgpack::type::array_ref > ar1 = msgpack::type::make_array_ref(v); + std::stringstream ss; + msgpack::pack(ss, ar1); + + msgpack::unpacked upd; + msgpack::unpack(upd, ss.str().data(), ss.str().size()); + EXPECT_EQ(upd.get().type, msgpack::type::ARRAY); + std::array v2; + msgpack::type::array_ref > ar2(v2); + upd.get().convert(ar2); + EXPECT_EQ(ar1, ar2); +} + +TEST(MSGPACK_ARRAY_REF, pack_unpack_convert_array_char_const) +{ + std::array v { { 'a', 'b', 'c' } }; + + std::array const& cv = v; + + msgpack::type::array_ref const> ar1 = msgpack::type::make_array_ref(cv); + std::stringstream ss; + msgpack::pack(ss, ar1); + + msgpack::unpacked upd; + msgpack::unpack(upd, ss.str().data(), ss.str().size()); + EXPECT_EQ(upd.get().type, msgpack::type::ARRAY); + std::array v2; + msgpack::type::array_ref > ar2(v2); + upd.get().convert(ar2); + EXPECT_EQ(ar1, ar2); +} + +TEST(MSGPACK_ARRAY_REF, pack_unpack_convert_array_unsigned_char) +{ + std::array v { { 'a', 'b', 'c' } }; + + msgpack::type::array_ref > ar1 = msgpack::type::make_array_ref(v); + std::stringstream ss; + msgpack::pack(ss, ar1); + + msgpack::unpacked upd; + msgpack::unpack(upd, ss.str().data(), ss.str().size()); + EXPECT_EQ(upd.get().type, msgpack::type::ARRAY); + std::array v2; + msgpack::type::array_ref > ar2(v2); + upd.get().convert(ar2); + EXPECT_EQ(ar1, ar2); +} + +TEST(MSGPACK_ARRAY_REF, pack_unpack_convert_array_unsigned_char_const) +{ + std::array v { { 'a', 'b', 'c' } }; + + std::array const& cv = v; + + msgpack::type::array_ref const> ar1 = msgpack::type::make_array_ref(cv); + std::stringstream ss; + msgpack::pack(ss, ar1); + + msgpack::unpacked upd; + msgpack::unpack(upd, ss.str().data(), ss.str().size()); + EXPECT_EQ(upd.get().type, msgpack::type::ARRAY); + std::array v2; + msgpack::type::array_ref > ar2(v2); + upd.get().convert(ar2); + EXPECT_EQ(ar1, ar2); +} + +TEST(MSGPACK_ARRAY_REF, object_with_zone_array_char) +{ + std::array v { { 'a', 'b', 'c' } }; + + msgpack::type::array_ref > ar1 = msgpack::type::make_array_ref(v); + msgpack::zone z; + msgpack::object obj(ar1, z); + + EXPECT_EQ(obj.type, msgpack::type::ARRAY); + std::array v2; + msgpack::type::array_ref > ar2(v2); + obj.convert(ar2); + EXPECT_EQ(ar1, ar2); +} + +TEST(MSGPACK_ARRAY_REF, object_with_zone_array_char_const) +{ + std::array v { { 'a', 'b', 'c' } }; + + std::array const& cv = v; + + msgpack::type::array_ref const> ar1 = msgpack::type::make_array_ref(cv); + msgpack::zone z; + msgpack::object obj(ar1, z); + + EXPECT_EQ(obj.type, msgpack::type::ARRAY); + std::array v2; + msgpack::type::array_ref > ar2(v2); + obj.convert(ar2); + EXPECT_EQ(ar1, ar2); +} + +TEST(MSGPACK_ARRAY_REF, object_with_zone_array_unsigned_char) +{ + std::array v { { 'a', 'b', 'c' } }; + + msgpack::type::array_ref > ar1 = msgpack::type::make_array_ref(v); + msgpack::zone z; + msgpack::object obj(ar1, z); + + EXPECT_EQ(obj.type, msgpack::type::ARRAY); + std::array v2; + msgpack::type::array_ref > ar2(v2); + obj.convert(ar2); + EXPECT_EQ(ar1, ar2); +} + +TEST(MSGPACK_ARRAY_REF, object_with_zone_array_unsigned_char_const) +{ + std::array v { { 'a', 'b', 'c' } }; + + std::array const& cv = v; + + msgpack::type::array_ref const> ar1 = msgpack::type::make_array_ref(cv); + msgpack::zone z; + msgpack::object obj(ar1, z); + + EXPECT_EQ(obj.type, msgpack::type::ARRAY); + std::array v2; + msgpack::type::array_ref > ar2(v2); + obj.convert(ar2); + EXPECT_EQ(ar1, ar2); +} + +#endif // !defined(MSGPACK_USE_CPP03) diff --git a/test/msgpack_container.cpp b/test/msgpack_container.cpp index 7962950c..ef1b85b0 100644 --- a/test/msgpack_container.cpp +++ b/test/msgpack_container.cpp @@ -72,6 +72,43 @@ TEST(MSGPACK_STL, simple_buffer_vector_char) } } +TEST(MSGPACK_STL, simple_buffer_vector_unsigned_char) +{ + typedef vector > type; + for (unsigned int k = 0; k < kLoop; k++) { + type val1; + for (unsigned int i = 0; i < kElements; i++) + val1.push_back(rand()); + msgpack::sbuffer sbuf; + msgpack::pack(sbuf, val1); + msgpack::unpacked ret; + msgpack::unpack(ret, sbuf.data(), sbuf.size()); + EXPECT_EQ(ret.get().type, msgpack::type::BIN); + type const& val2 = ret.get().as(); + EXPECT_EQ(val1.size(), val2.size()); + EXPECT_TRUE(equal(val1.begin(), val1.end(), val2.begin())); + } +} + +TEST(MSGPACK_STL, simple_buffer_vector_uint8_t) +{ + if (!msgpack::is_same::value) return; + typedef vector > type; + for (unsigned int k = 0; k < kLoop; k++) { + type val1; + for (unsigned int i = 0; i < kElements; i++) + val1.push_back(rand()); + msgpack::sbuffer sbuf; + msgpack::pack(sbuf, val1); + msgpack::unpacked ret; + msgpack::unpack(ret, sbuf.data(), sbuf.size()); + EXPECT_EQ(ret.get().type, msgpack::type::BIN); + type const& val2 = ret.get().as(); + EXPECT_EQ(val1.size(), val2.size()); + EXPECT_TRUE(equal(val1.begin(), val1.end(), val2.begin())); + } +} + TEST(MSGPACK_STL, simple_buffer_vector_bool) { typedef vector > type; diff --git a/test/msgpack_cpp11.cpp b/test/msgpack_cpp11.cpp index b5b8b523..79aab951 100644 --- a/test/msgpack_cpp11.cpp +++ b/test/msgpack_cpp11.cpp @@ -93,6 +93,24 @@ TEST(MSGPACK_CPP11, simple_buffer_array_char) } } +TEST(MSGPACK_CPP11, simple_buffer_array_unsigned_char) +{ + if (!msgpack::is_same::value) return; + for (unsigned int k = 0; k < kLoop; k++) { + array val1; + for (unsigned int i = 0; i < kElements; i++) + val1[i] = rand(); + msgpack::sbuffer sbuf; + msgpack::pack(sbuf, val1); + msgpack::unpacked ret; + msgpack::unpack(ret, sbuf.data(), sbuf.size()); + EXPECT_EQ(ret.get().type, msgpack::type::BIN); + array val2 = ret.get().as >(); + EXPECT_EQ(val1.size(), val2.size()); + EXPECT_TRUE(equal(val1.begin(), val1.end(), val2.begin())); + } +} + // strong typedefs namespace test { diff --git a/test/object_with_zone.cpp b/test/object_with_zone.cpp index 58a62404..af21dc07 100644 --- a/test/object_with_zone.cpp +++ b/test/object_with_zone.cpp @@ -240,6 +240,39 @@ TEST(object_without_zone, vector_char) } } +// vector_unsgined_char +TEST(object_with_zone, vector_unsigned_char) +{ + if (!msgpack::is_same::value) return; + for (unsigned int k = 0; k < kLoop; k++) { + vector v1; + v1.push_back(1); + for (unsigned int i = 1; i < kElements; i++) + v1.push_back(static_cast(i)); + msgpack::zone z; + msgpack::object obj(v1, z); + EXPECT_EQ(obj.as >(), v1); + v1.front() = 42; + EXPECT_EQ(obj.as >().front(), 1); + } +} + +TEST(object_without_zone, vector_unsigned_char) +{ + if (!msgpack::is_same::value) return; + for (unsigned int k = 0; k < kLoop; k++) { + vector v1; + v1.push_back(1); + for (unsigned int i = 1; i < kElements; i++) + v1.push_back(static_cast(i)); + msgpack::object obj(v1); + EXPECT_EQ(obj.as >(), v1); + v1.front() = 42; + // obj refer to v1 + EXPECT_EQ(obj.as >().front(), 42); + } +} + // list TEST(object_with_zone, list) { @@ -830,6 +863,40 @@ TEST(object_without_zone, array_char) } } +TEST(object_with_zone, array_unsigned_char) +{ + if (!msgpack::is_same::value) return; + typedef array test_t; + for (unsigned int k = 0; k < kLoop; k++) { + test_t v1; + v1[0] = 1; + for (unsigned int i = 1; i < kElements; i++) + v1[i] = rand(); + msgpack::zone z; + msgpack::object obj(v1, z); + EXPECT_EQ(obj.as(), v1); + v1.front() = 42; + EXPECT_EQ(obj.as().front(), 1); + } +} + +TEST(object_without_zone, array_unsigned_char) +{ + if (!msgpack::is_same::value) return; + typedef array test_t; + for (unsigned int k = 0; k < kLoop; k++) { + test_t v1; + v1[0] = 1; + for (unsigned int i = 1; i < kElements; i++) + v1[i] = rand(); + msgpack::object obj(v1); + EXPECT_EQ(obj.as(), v1); + v1.front() = 42; + // obj refer to v1 + EXPECT_EQ(obj.as().front(), 42); + } +} + TEST(object_with_zone, forward_list) {