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