Skip to content

Commit 1155bab

Browse files
committed
Added wstring adaptor.
1 parent 83a82e3 commit 1155bab

File tree

11 files changed

+234
-11
lines changed

11 files changed

+234
-11
lines changed

Files.cmake

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ IF (MSGPACK_ENABLE_CXX)
231231
include/msgpack/adaptor/vector_bool.hpp
232232
include/msgpack/adaptor/vector_char.hpp
233233
include/msgpack/adaptor/vector_unsigned_char.hpp
234+
include/msgpack/adaptor/wstring.hpp
234235
include/msgpack/cpp_config.hpp
235236
include/msgpack/cpp_config_decl.hpp
236237
include/msgpack/create_object_visitor.hpp
@@ -605,6 +606,7 @@ IF (MSGPACK_ENABLE_CXX)
605606
include/msgpack/v1/adaptor/vector_bool.hpp
606607
include/msgpack/v1/adaptor/vector_char.hpp
607608
include/msgpack/v1/adaptor/vector_unsigned_char.hpp
609+
include/msgpack/v1/adaptor/wstring.hpp
608610
include/msgpack/v1/cpp_config.hpp
609611
include/msgpack/v1/cpp_config_decl.hpp
610612
include/msgpack/v1/detail/cpp03_zone.hpp
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//
2+
// MessagePack for C++ static resolution routine
3+
//
4+
// Copyright (C) 2018 KONDO Takatoshi
5+
//
6+
// Distributed under the Boost Software License, Version 1.0.
7+
// (See accompanying file LICENSE_1_0.txt or copy at
8+
// http://www.boost.org/LICENSE_1_0.txt)
9+
//
10+
#ifndef MSGPACK_TYPE_WSTRING_HPP
11+
#define MSGPACK_TYPE_WSTRING_HPP
12+
13+
#include "msgpack/v1/adaptor/wstring.hpp"
14+
15+
#endif // MSGPACK_TYPE_WSTRING_HPP

include/msgpack/type.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "adaptor/vector_bool.hpp"
2222
#include "adaptor/vector_char.hpp"
2323
#include "adaptor/vector_unsigned_char.hpp"
24+
#include "adaptor/wstring.hpp"
2425
#include "adaptor/msgpack_tuple.hpp"
2526
#include "adaptor/define.hpp"
2627

include/msgpack/v1/adaptor/int.hpp

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,9 @@ inline T convert_integer(msgpack::object const& o)
6464
}
6565

6666
template <>
67-
struct object_char_sign<true> {
67+
struct object_sign<true> {
6868
template <typename T>
69-
static typename msgpack::enable_if<msgpack::is_same<T, char>::value>::type
70-
make(msgpack::object& o, T v) {
69+
static void make(msgpack::object& o, T v) {
7170
if (v < 0) {
7271
o.type = msgpack::type::NEGATIVE_INTEGER;
7372
o.via.i64 = v;
@@ -80,15 +79,17 @@ struct object_char_sign<true> {
8079
};
8180

8281
template <>
83-
struct object_char_sign<false> {
84-
static void make(msgpack::object& o, char v) {
82+
struct object_sign<false> {
83+
template <typename T>
84+
static void make(msgpack::object& o, T v) {
8585
o.type = msgpack::type::POSITIVE_INTEGER;
8686
o.via.u64 = v;
8787
}
8888
};
8989

90-
inline void object_char(msgpack::object& o, char v) {
91-
return object_char_sign<is_signed<char>::value>::make(o, v);
90+
template <typename T>
91+
inline void object_char(msgpack::object& o, T v) {
92+
return object_sign<is_signed<T>::value>::make(o, v);
9293
}
9394

9495
} // namespace detail
@@ -102,6 +103,12 @@ struct convert<char> {
102103
{ v = type::detail::convert_integer<char>(o); return o; }
103104
};
104105

106+
template <>
107+
struct convert<wchar_t> {
108+
msgpack::object const& operator()(msgpack::object const& o, wchar_t& v) const
109+
{ v = type::detail::convert_integer<wchar_t>(o); return o; }
110+
};
111+
105112
template <>
106113
struct convert<signed char> {
107114
msgpack::object const& operator()(msgpack::object const& o, signed char& v) const
@@ -171,6 +178,13 @@ struct pack<char> {
171178
{ o.pack_char(v); return o; }
172179
};
173180

181+
template <>
182+
struct pack<wchar_t> {
183+
template <typename Stream>
184+
msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, wchar_t v) const
185+
{ o.pack_wchar(v); return o; }
186+
};
187+
174188
template <>
175189
struct pack<signed char> {
176190
template <typename Stream>
@@ -249,6 +263,12 @@ struct object<char> {
249263
{ type::detail::object_char(o, v); }
250264
};
251265

266+
template <>
267+
struct object<wchar_t> {
268+
void operator()(msgpack::object& o, wchar_t v) const
269+
{ type::detail::object_char(o, v); }
270+
};
271+
252272
template <>
253273
struct object<signed char> {
254274
void operator()(msgpack::object& o, signed char v) const {
@@ -367,6 +387,13 @@ struct object_with_zone<char> {
367387
}
368388
};
369389

390+
template <>
391+
struct object_with_zone<wchar_t> {
392+
void operator()(msgpack::object::with_zone& o, wchar_t v) const {
393+
static_cast<msgpack::object&>(o) << v;
394+
}
395+
};
396+
370397
template <>
371398
struct object_with_zone<signed char> {
372399
void operator()(msgpack::object::with_zone& o, signed char v) const {

include/msgpack/v1/adaptor/int_decl.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,10 @@ template <typename T>
3333
T convert_integer(msgpack::object const& o);
3434

3535
template <bool Signed>
36-
struct object_char_sign;
36+
struct object_sign;
3737

38-
void object_char(msgpack::object& o, char v);
38+
template <typename T>
39+
void object_char(msgpack::object& o, T v);
3940

4041
} // namespace detail
4142
} // namespace type
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
//
2+
// MessagePack for C++ static resolution routine
3+
//
4+
// Copyright (C) 2018 KONDO Takatoshi
5+
//
6+
// Distributed under the Boost Software License, Version 1.0.
7+
// (See accompanying file LICENSE_1_0.txt or copy at
8+
// http://www.boost.org/LICENSE_1_0.txt)
9+
//
10+
#ifndef MSGPACK_V1_TYPE_WSTRING_HPP
11+
#define MSGPACK_V1_TYPE_WSTRING_HPP
12+
13+
#include "msgpack/versioning.hpp"
14+
#include "msgpack/adaptor/adaptor_base.hpp"
15+
#include "msgpack/adaptor/check_container_size.hpp"
16+
17+
#include <vector>
18+
19+
namespace msgpack {
20+
21+
/// @cond
22+
MSGPACK_API_VERSION_NAMESPACE(v1) {
23+
/// @endcond
24+
25+
namespace adaptor {
26+
27+
#if !defined(MSGPACK_USE_CPP03)
28+
29+
template <>
30+
struct as<std::wstring> {
31+
std::wstring operator()(const msgpack::object& o) const {
32+
if (o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); }
33+
std::wstring v;
34+
v.reserve(o.via.array.size);
35+
if (o.via.array.size > 0) {
36+
msgpack::object* p = o.via.array.ptr;
37+
msgpack::object* const pend = o.via.array.ptr + o.via.array.size;
38+
do {
39+
v.push_back(p->as<wchar_t>());
40+
++p;
41+
} while (p < pend);
42+
}
43+
return v;
44+
}
45+
};
46+
47+
#endif // !defined(MSGPACK_USE_CPP03)
48+
49+
template <>
50+
struct convert<std::wstring> {
51+
msgpack::object const& operator()(msgpack::object const& o, std::wstring& v) const {
52+
if (o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); }
53+
v.resize(o.via.array.size);
54+
if (o.via.array.size > 0) {
55+
msgpack::object* p = o.via.array.ptr;
56+
msgpack::object* const pend = o.via.array.ptr + o.via.array.size;
57+
std::wstring::iterator it = v.begin();
58+
do {
59+
p->convert(*it);
60+
++p;
61+
++it;
62+
} while(p < pend);
63+
}
64+
return o;
65+
}
66+
};
67+
68+
template <>
69+
struct pack<std::wstring> {
70+
template <typename Stream>
71+
msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, const std::wstring& v) const {
72+
uint32_t size = checked_get_container_size(v.size());
73+
o.pack_array(size);
74+
for (std::wstring::const_iterator it(v.begin()), it_end(v.end());
75+
it != it_end; ++it) {
76+
o.pack(*it);
77+
}
78+
return o;
79+
}
80+
};
81+
82+
template <>
83+
struct object_with_zone<std::wstring> {
84+
void operator()(msgpack::object::with_zone& o, const std::wstring& v) const {
85+
o.type = msgpack::type::ARRAY;
86+
if (v.empty()) {
87+
o.via.array.ptr = MSGPACK_NULLPTR;
88+
o.via.array.size = 0;
89+
}
90+
else {
91+
uint32_t size = checked_get_container_size(v.size());
92+
msgpack::object* p = static_cast<msgpack::object*>(o.zone.allocate_align(sizeof(msgpack::object)*size, MSGPACK_ZONE_ALIGNOF(msgpack::object)));
93+
msgpack::object* const pend = p + size;
94+
o.via.array.ptr = p;
95+
o.via.array.size = size;
96+
std::wstring::const_iterator it(v.begin());
97+
do {
98+
#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) && !defined(__clang__)
99+
#pragma GCC diagnostic push
100+
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
101+
#endif // (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) && !defined(__clang__)
102+
*p = msgpack::object(*it, o.zone);
103+
#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) && !defined(__clang__)
104+
#pragma GCC diagnostic pop
105+
#endif // (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) && !defined(__clang__)
106+
++p;
107+
++it;
108+
} while(p < pend);
109+
}
110+
}
111+
};
112+
113+
} // namespace adaptor
114+
115+
/// @cond
116+
} // MSGPACK_API_VERSION_NAMESPACE(v1)
117+
/// @endcond
118+
119+
} // namespace msgpack
120+
121+
#endif // MSGPACK_V1_TYPE_WSTRING_HPP

include/msgpack/v1/pack.hpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,20 @@ class packer {
271271
*/
272272
packer<Stream>& pack_char(char d);
273273

274+
/// Packing wchar_t
275+
/**
276+
* The byte size of the packed data depends on `d`.
277+
* If `d` is zero or positive, the packed type is positive fixnum, or uint*,
278+
* else the packed type is negative fixnum, or int*
279+
* The minimum byte size expression is used.
280+
* See https://github.com/msgpack/msgpack/blob/master/spec.md#formats-int
281+
*
282+
* @param d a packing object.
283+
*
284+
* @return The reference of `*this`.
285+
*/
286+
packer<Stream>& pack_wchar(wchar_t d);
287+
274288
/// Packing signed char
275289
/**
276290
* The byte size of the packed data depends on `d`.
@@ -820,6 +834,18 @@ inline packer<Stream>& packer<Stream>::pack_char(char d)
820834
return *this;
821835
}
822836

837+
template <typename Stream>
838+
inline packer<Stream>& packer<Stream>::pack_wchar(wchar_t d)
839+
{
840+
if (d < 0) {
841+
pack_imp_int64(static_cast<int64_t>(d));
842+
}
843+
else {
844+
pack_imp_uint64(static_cast<uint64_t>(d));
845+
}
846+
return *this;
847+
}
848+
823849
template <typename Stream>
824850
inline packer<Stream>& packer<Stream>::pack_signed_char(signed char d)
825851
{

include/msgpack/v2/adaptor/int_decl.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ struct is_signed;
3030

3131

3232
template <bool Signed>
33-
struct object_char_sign;
33+
struct object_sign;
3434

3535
//using v1::type::detail::convert_integer_sign;
3636

include/msgpack/v3/adaptor/int_decl.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ struct is_signed;
3030

3131

3232
template <bool Signed>
33-
struct object_char_sign;
33+
struct object_sign;
3434

3535
//using v2::type::detail::convert_integer_sign;
3636

test/msgpack_basic.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,3 +614,22 @@ TEST(MSGPACK_STL, simple_buffer_non_const_cstring)
614614
EXPECT_EQ(val1, val2);
615615
}
616616
}
617+
618+
TEST(MSGPACK_STL, simple_buffer_wstring)
619+
{
620+
for (unsigned int k = 0; k < kLoop; k++) {
621+
wstring val1;
622+
for (unsigned int i = 0; i < kElements; i++)
623+
val1 += L'a' + rand() % 26;
624+
msgpack::sbuffer sbuf;
625+
msgpack::pack(sbuf, val1);
626+
msgpack::object_handle oh =
627+
msgpack::unpack(sbuf.data(), sbuf.size());
628+
EXPECT_EQ(oh.get().type, msgpack::type::ARRAY);
629+
wstring val2 = oh.get().as<wstring>();
630+
EXPECT_EQ(val1, val2);
631+
wstring val3;
632+
oh.get().convert(val3);
633+
EXPECT_EQ(val1, val3);
634+
}
635+
}

0 commit comments

Comments
 (0)