MessagePack for C++
ext.hpp
Go to the documentation of this file.
1 //
2 // MessagePack for C++ static resolution routine
3 //
4 // Copyright (C) 2015-2016 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_EXT_HPP
11 #define MSGPACK_V1_TYPE_EXT_HPP
12 
15 #include <cstring>
16 #include <string>
17 
18 namespace msgpack {
19 
23 
24 namespace type {
25 
26 class ext {
27 public:
28  ext() : m_data(1, 0) {}
29  ext(int8_t t, const char* p, uint32_t s) {
30  msgpack::detail::check_container_size_for_ext<sizeof(std::size_t)>(s);
31  m_data.reserve(static_cast<std::size_t>(s) + 1);
32  m_data.push_back(static_cast<char>(t));
33  m_data.insert(m_data.end(), p, p + s);
34  }
35  ext(int8_t t, uint32_t s) {
36  msgpack::detail::check_container_size_for_ext<sizeof(std::size_t)>(s);
37  m_data.resize(static_cast<std::size_t>(s) + 1);
38  m_data[0] = static_cast<char>(t);
39  }
40  explicit ext(ext_ref const&);
41  int8_t type() const {
42  return static_cast<int8_t>(m_data[0]);
43  }
44  const char* data() const {
45  return &m_data[0] + 1;
46  }
47  char* data() {
48  return &m_data[0] + 1;
49  }
50  uint32_t size() const {
51  return static_cast<uint32_t>(m_data.size()) - 1;
52  }
53  bool operator== (const ext& x) const {
54  return m_data == x.m_data;
55  }
56 
57  bool operator!= (const ext& x) const {
58  return !(*this == x);
59  }
60 
61  bool operator< (const ext& x) const {
62  return m_data < x.m_data;
63  }
64 
65  bool operator> (const ext& x) const {
66  return m_data > x.m_data;
67  }
68 private:
69  std::vector<char> m_data;
70  friend class ext_ref;
71 };
72 
73 } // namespace type
74 
75 namespace adaptor {
76 
77 template <>
80  if(o.type != msgpack::type::EXT) {
81  throw msgpack::type_error();
82  }
83  v = msgpack::type::ext(o.via.ext.type(), o.via.ext.data(), o.via.ext.size);
84  return o;
85  }
86 };
87 
88 template <>
90  template <typename Stream>
92  // size limit has already been checked at ext's constructor
93  uint32_t size = v.size();
94  o.pack_ext(size, v.type());
95  o.pack_ext_body(v.data(), size);
96  return o;
97  }
98 };
99 
100 template <>
103  // size limit has already been checked at ext's constructor
104  uint32_t size = v.size();
106  char* ptr = static_cast<char*>(o.zone.allocate_align(size + 1, MSGPACK_ZONE_ALIGNOF(char)));
107  o.via.ext.ptr = ptr;
108  o.via.ext.size = size;
109  ptr[0] = static_cast<char>(v.type());
110  std::memcpy(ptr + 1, v.data(), size);
111  }
112 };
113 
114 } // namespace adaptor
115 
116 namespace type {
117 
118 class ext_ref {
119 public:
120  // ext_ref should be default constructible to support 'convert'.
121  // A default constructed ext_ref object::m_ptr doesn't have the buffer to point to.
122  // In order to avoid nullptr checking branches, m_ptr points to m_size.
123  // So type() returns unspecified but valid value. It might be a zero because m_size
124  // is initialized as zero, but shouldn't assume that.
125  ext_ref() : m_ptr(static_cast<char*>(static_cast<void*>(&m_size))), m_size(0) {}
126  ext_ref(const char* p, uint32_t s) :
127  m_ptr(s == 0 ? static_cast<char*>(static_cast<void*>(&m_size)) : p),
128  m_size(s == 0 ? 0 : s - 1) {
129  msgpack::detail::check_container_size_for_ext<sizeof(std::size_t)>(s);
130  }
131 
132  // size limit has already been checked at ext's constructor
133  ext_ref(ext const& x) : m_ptr(&x.m_data[0]), m_size(x.size()) {}
134 
135  const char* data() const {
136  return m_ptr + 1;
137  }
138 
139  uint32_t size() const {
140  return m_size;
141  }
142 
143  int8_t type() const {
144  return static_cast<int8_t>(m_ptr[0]);
145  }
146 
147  std::string str() const {
148  return std::string(m_ptr + 1, m_size);
149  }
150 
151  bool operator== (const ext_ref& x) const {
152  return m_size == x.m_size && std::memcmp(m_ptr, x.m_ptr, m_size) == 0;
153  }
154 
155  bool operator!= (const ext_ref& x) const {
156  return !(*this == x);
157  }
158 
159  bool operator< (const ext_ref& x) const {
160  if (m_size < x.m_size) return true;
161  if (m_size > x.m_size) return false;
162  return std::memcmp(m_ptr, x.m_ptr, m_size) < 0;
163  }
164 
165  bool operator> (const ext_ref& x) const {
166  if (m_size > x.m_size) return true;
167  if (m_size < x.m_size) return false;
168  return std::memcmp(m_ptr, x.m_ptr, m_size) > 0;
169  }
170 
171 private:
172  const char* m_ptr;
173  uint32_t m_size;
174  friend struct adaptor::object<msgpack::type::ext_ref>;
175 };
176 
177 inline ext::ext(ext_ref const& x) {
178  // size limit has already been checked at ext_ref's constructor
179  m_data.reserve(x.size() + 1);
180 
181  m_data.push_back(static_cast<char>(x.type()));
182  m_data.insert(m_data.end(), x.data(), x.data() + x.size());
183 }
184 
185 } // namespace type
186 
187 namespace adaptor {
188 
189 template <>
192  if(o.type != msgpack::type::EXT) { throw msgpack::type_error(); }
193  v = msgpack::type::ext_ref(o.via.ext.ptr, o.via.ext.size + 1);
194  return o;
195  }
196 };
197 
198 template <>
200  template <typename Stream>
202  // size limit has already been checked at ext_ref's constructor
203  uint32_t size = v.size();
204  o.pack_ext(size, v.type());
205  o.pack_ext_body(v.data(), size);
206  return o;
207  }
208 };
209 
210 template <>
213  // size limit has already been checked at ext_ref's constructor
214  uint32_t size = v.size();
216  o.via.ext.ptr = v.m_ptr;
217  o.via.ext.size = size;
218  }
219 };
220 
221 template <>
224  static_cast<msgpack::object&>(o) << v;
225  }
226 };
227 
228 } // namespace adaptor
229 
231 } // MSGPACK_API_VERSION_NAMESPACE(v1)
233 
234 } // namespace msgpack
235 
236 #endif // MSGPACK_V1_TYPE_EXT_HPP
The class template that supports continuous packing.
Definition: pack.hpp:33
packer< Stream > & pack_ext(size_t l, int8_t type)
Packing ext header, type, and length.
Definition: pack.hpp:1316
packer< Stream > & pack_ext_body(const char *b, uint32_t l)
Packing ext body.
Definition: pack.hpp:1375
Definition: ext.hpp:118
bool operator!=(const ext_ref &x) const
Definition: ext.hpp:155
bool operator<(const ext_ref &x) const
Definition: ext.hpp:159
bool operator==(const ext_ref &x) const
Definition: ext.hpp:151
ext_ref(ext const &x)
Definition: ext.hpp:133
int8_t type() const
Definition: ext.hpp:143
std::string str() const
Definition: ext.hpp:147
uint32_t size() const
Definition: ext.hpp:139
bool operator>(const ext_ref &x) const
Definition: ext.hpp:165
ext_ref(const char *p, uint32_t s)
Definition: ext.hpp:126
const char * data() const
Definition: ext.hpp:135
ext_ref()
Definition: ext.hpp:125
Definition: ext.hpp:26
ext(int8_t t, uint32_t s)
Definition: ext.hpp:35
bool operator>(const ext &x) const
Definition: ext.hpp:65
bool operator!=(const ext &x) const
Definition: ext.hpp:57
uint32_t size() const
Definition: ext.hpp:50
char * data()
Definition: ext.hpp:47
bool operator==(const ext &x) const
Definition: ext.hpp:53
const char * data() const
Definition: ext.hpp:44
ext()
Definition: ext.hpp:28
int8_t type() const
Definition: ext.hpp:41
ext(int8_t t, const char *p, uint32_t s)
Definition: ext.hpp:29
bool operator<(const ext &x) const
Definition: ext.hpp:61
Definition: object_fwd.hpp:231
void * allocate_align(size_t size, size_t align=MSGPACK_ZONE_ALIGN)
Definition: cpp03_zone.hpp:256
std::size_t size(T const &t)
Definition: size_equal_only.hpp:24
@ EXT
Definition: object_fwd_decl.hpp:42
Definition: adaptor_base.hpp:15
msgpack::object const & operator()(msgpack::object const &o, msgpack::type::ext &v) const
Definition: ext.hpp:79
msgpack::object const & operator()(msgpack::object const &o, msgpack::type::ext_ref &v) const
Definition: ext.hpp:191
Definition: adaptor_base.hpp:27
void operator()(msgpack::object &o, const msgpack::type::ext_ref &v) const
Definition: ext.hpp:212
void operator()(msgpack::object::with_zone &o, const msgpack::type::ext &v) const
Definition: ext.hpp:102
void operator()(msgpack::object::with_zone &o, const msgpack::type::ext_ref &v) const
Definition: ext.hpp:223
Definition: adaptor_base.hpp:43
Definition: adaptor_base.hpp:38
msgpack::packer< Stream > & operator()(msgpack::packer< Stream > &o, const msgpack::type::ext &v) const
Definition: ext.hpp:91
msgpack::packer< Stream > & operator()(msgpack::packer< Stream > &o, const msgpack::type::ext_ref &v) const
Definition: ext.hpp:201
Definition: adaptor_base.hpp:32
Definition: object.hpp:35
msgpack::zone & zone
Definition: object.hpp:37
const char * data() const
Definition: object_fwd.hpp:44
int8_t type() const
Definition: object_fwd.hpp:43
const char * ptr
Definition: object_fwd.hpp:46
uint32_t size
Definition: object_fwd.hpp:45
Object class that corresponding to MessagePack format object.
Definition: object_fwd.hpp:75
union_type via
Definition: object_fwd.hpp:93
msgpack::type::object_type type
Definition: object_fwd.hpp:92
msgpack::object_ext ext
Definition: object_fwd.hpp:89
#define MSGPACK_ZONE_ALIGNOF(type)
Definition: cpp03_zone_decl.hpp:30
#define MSGPACK_API_VERSION_NAMESPACE(ns)
Definition: versioning.hpp:66