MessagePack for C++
create_object_visitor.hpp
Go to the documentation of this file.
1 //
2 // MessagePack for C++ deserializing routine
3 //
4 // Copyright (C) 2017 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_V2_CREATE_OBJECT_VISITOR_HPP
11 #define MSGPACK_V2_CREATE_OBJECT_VISITOR_HPP
12 
13 #include <boost/assert.hpp>
14 
15 #include "msgpack/unpack_decl.hpp"
19 
20 namespace msgpack {
21 
25 
26 namespace detail {
27 
28 class create_object_visitor : public msgpack::v2::null_visitor {
29 public:
30  create_object_visitor(unpack_reference_func f, void* user_data, unpack_limit const& limit)
31  :m_func(f), m_user_data(user_data), m_limit(limit) {
33  m_stack.push_back(&m_obj);
34  }
35 
36 #if !defined(MSGPACK_USE_CPP03)
38  :m_func(other.m_func),
39  m_user_data(other.m_user_data),
40  m_limit(std::move(other.m_limit)),
41  m_stack(std::move(other.m_stack)),
42  m_zone(other.m_zone),
43  m_referenced(other.m_referenced) {
44  other.m_zone = MSGPACK_NULLPTR;
45  m_stack[0] = &m_obj;
46  }
48  this->~create_object_visitor();
49  new (this) create_object_visitor(std::move(other));
50  return *this;
51  }
52 #endif // !defined(MSGPACK_USE_CPP03)
53 
54  void init() {
55  m_stack.resize(1);
57  m_stack[0] = &m_obj;
58  }
59  msgpack::object const& data() const
60  {
61  return m_obj;
62  }
63  msgpack::zone const& zone() const { return *m_zone; }
64  msgpack::zone& zone() { return *m_zone; }
66  bool referenced() const { return m_referenced; }
68  // visit functions
69  bool visit_nil() {
70  msgpack::object* obj = m_stack.back();
71  obj->type = msgpack::type::NIL;
72  return true;
73  }
74  bool visit_boolean(bool v) {
75  msgpack::object* obj = m_stack.back();
77  obj->via.boolean = v;
78  return true;
79  }
80  bool visit_positive_integer(uint64_t v) {
81  msgpack::object* obj = m_stack.back();
83  obj->via.u64 = v;
84  return true;
85  }
86  bool visit_negative_integer(int64_t v) {
87  msgpack::object* obj = m_stack.back();
88  if(v >= 0) {
90  obj->via.u64 = static_cast<uint64_t>(v);
91  }
92  else {
94  obj->via.i64 = v;
95  }
96  return true;
97  }
98  bool visit_float32(float v) {
99  msgpack::object* obj = m_stack.back();
101  obj->via.f64 = v;
102  return true;
103  }
104  bool visit_float64(double v) {
105  msgpack::object* obj = m_stack.back();
107  obj->via.f64 = v;
108  return true;
109  }
110  bool visit_str(const char* v, uint32_t size) {
111  BOOST_ASSERT(v || size == 0);
112  if (size > m_limit.str()) throw msgpack::str_size_overflow("str size overflow");
113  msgpack::object* obj = m_stack.back();
114  obj->type = msgpack::type::STR;
115  if (m_func && m_func(obj->type, size, m_user_data)) {
116  obj->via.str.ptr = v;
117  obj->via.str.size = size;
118  set_referenced(true);
119  }
120  else {
121  if (v) {
122  char* tmp = static_cast<char*>(zone().allocate_align(size, MSGPACK_ZONE_ALIGNOF(char)));
123  std::memcpy(tmp, v, size);
124  obj->via.str.ptr = tmp;
125  obj->via.str.size = size;
126  }
127  else {
128  obj->via.str.ptr = MSGPACK_NULLPTR;
129  obj->via.str.size = 0;
130  }
131  }
132  return true;
133  }
134  bool visit_bin(const char* v, uint32_t size) {
135  BOOST_ASSERT(v || size == 0);
136  if (size > m_limit.bin()) throw msgpack::bin_size_overflow("bin size overflow");
137  msgpack::object* obj = m_stack.back();
138  obj->type = msgpack::type::BIN;
139  if (m_func && m_func(obj->type, size, m_user_data)) {
140  obj->via.bin.ptr = v;
141  obj->via.bin.size = size;
142  set_referenced(true);
143  }
144  else {
145  if (v) {
146  char* tmp = static_cast<char*>(zone().allocate_align(size, MSGPACK_ZONE_ALIGNOF(char)));
147  std::memcpy(tmp, v, size);
148  obj->via.bin.ptr = tmp;
149  obj->via.bin.size = size;
150  }
151  else {
152  obj->via.bin.ptr = MSGPACK_NULLPTR;
153  obj->via.bin.size = 0;
154  }
155  }
156  return true;
157  }
158  bool visit_ext(const char* v, uint32_t size) {
159  BOOST_ASSERT(v || size == 0);
160  if (size > m_limit.ext()) throw msgpack::ext_size_overflow("ext size overflow");
161  msgpack::object* obj = m_stack.back();
162  obj->type = msgpack::type::EXT;
163  if (m_func && m_func(obj->type, size, m_user_data)) {
164  obj->via.ext.ptr = v;
165  obj->via.ext.size = static_cast<uint32_t>(size - 1);
166  set_referenced(true);
167  }
168  else {
169  if (v) {
170  char* tmp = static_cast<char*>(zone().allocate_align(size, MSGPACK_ZONE_ALIGNOF(char)));
171  std::memcpy(tmp, v, size);
172  obj->via.ext.ptr = tmp;
173  obj->via.ext.size = static_cast<uint32_t>(size - 1);
174  }
175  else {
176  obj->via.ext.ptr = MSGPACK_NULLPTR;
177  obj->via.ext.size = 0;
178  }
179  }
180  return true;
181  }
182  bool start_array(uint32_t num_elements) {
183  if (num_elements > m_limit.array()) throw msgpack::array_size_overflow("array size overflow");
184  if (m_stack.size() > m_limit.depth()) throw msgpack::depth_size_overflow("depth size overflow");
185  msgpack::object* obj = m_stack.back();
186  obj->type = msgpack::type::ARRAY;
187  obj->via.array.size = num_elements;
188  if (num_elements == 0) {
189  obj->via.array.ptr = MSGPACK_NULLPTR;
190  }
191  else {
192 
193 #if SIZE_MAX == UINT_MAX
194  if (num_elements > SIZE_MAX/sizeof(msgpack::object))
195  throw msgpack::array_size_overflow("array size overflow");
196 #endif // SIZE_MAX == UINT_MAX
197 
198  size_t size = num_elements*sizeof(msgpack::object);
199  obj->via.array.ptr =
201  }
202  m_stack.push_back(obj->via.array.ptr);
203  return true;
204  }
206  return true;
207  }
208  bool end_array_item() {
209  ++m_stack.back();
210  return true;
211  }
212  bool end_array() {
213  m_stack.pop_back();
214  return true;
215  }
216  bool start_map(uint32_t num_kv_pairs) {
217  if (num_kv_pairs > m_limit.map()) throw msgpack::map_size_overflow("map size overflow");
218  if (m_stack.size() > m_limit.depth()) throw msgpack::depth_size_overflow("depth size overflow");
219  msgpack::object* obj = m_stack.back();
220  obj->type = msgpack::type::MAP;
221  obj->via.map.size = num_kv_pairs;
222  if (num_kv_pairs == 0) {
223  obj->via.map.ptr = MSGPACK_NULLPTR;
224  }
225  else {
226 
227 #if SIZE_MAX == UINT_MAX
228  if (num_kv_pairs > SIZE_MAX/sizeof(msgpack::object_kv))
229  throw msgpack::map_size_overflow("map size overflow");
230 #endif // SIZE_MAX == UINT_MAX
231  size_t size = num_kv_pairs*sizeof(msgpack::object_kv);
232  obj->via.map.ptr =
234  }
235  m_stack.push_back(reinterpret_cast<msgpack::object*>(obj->via.map.ptr));
236  return true;
237  }
238  bool start_map_key() {
239  return true;
240  }
241  bool end_map_key() {
242  ++m_stack.back();
243  return true;
244  }
246  return true;
247  }
248  bool end_map_value() {
249  ++m_stack.back();
250  return true;
251  }
252  bool end_map() {
253  m_stack.pop_back();
254  return true;
255  }
256  void parse_error(size_t /*parsed_offset*/, size_t /*error_offset*/) {
257  throw msgpack::parse_error("parse error");
258  }
259  void insufficient_bytes(size_t /*parsed_offset*/, size_t /*error_offset*/) {
260  throw msgpack::insufficient_bytes("insufficient bytes");
261  }
262 private:
263 public:
265  void* m_user_data;
268  std::vector<msgpack::object*> m_stack;
271 };
272 
273 } // detail
274 
276 } // MSGPACK_API_VERSION_NAMESPACE(v2)
278 
279 } // namespace msgpack
280 
281 #endif // MSGPACK_V2_CREATE_OBJECT_VISITOR_HPP
Definition: create_object_visitor.hpp:28
bool visit_float64(double v)
Definition: create_object_visitor.hpp:104
bool end_array()
Definition: create_object_visitor.hpp:212
bool visit_ext(const char *v, uint32_t size)
Definition: create_object_visitor.hpp:158
bool end_map()
Definition: create_object_visitor.hpp:252
std::vector< msgpack::object * > m_stack
Definition: create_object_visitor.hpp:268
bool visit_positive_integer(uint64_t v)
Definition: create_object_visitor.hpp:80
bool visit_negative_integer(int64_t v)
Definition: create_object_visitor.hpp:86
void set_referenced(bool referenced)
Definition: create_object_visitor.hpp:67
bool m_referenced
Definition: create_object_visitor.hpp:270
msgpack::object m_obj
Definition: create_object_visitor.hpp:267
msgpack::object const & data() const
Definition: create_object_visitor.hpp:59
create_object_visitor & operator=(create_object_visitor &&other)
Definition: create_object_visitor.hpp:47
void insufficient_bytes(size_t, size_t)
Definition: create_object_visitor.hpp:259
bool end_array_item()
Definition: create_object_visitor.hpp:208
msgpack::zone const & zone() const
Definition: create_object_visitor.hpp:63
void init()
Definition: create_object_visitor.hpp:54
bool end_map_value()
Definition: create_object_visitor.hpp:248
void set_zone(msgpack::zone &zone)
Definition: create_object_visitor.hpp:65
bool start_map_key()
Definition: create_object_visitor.hpp:238
bool visit_str(const char *v, uint32_t size)
Definition: create_object_visitor.hpp:110
unpack_limit m_limit
Definition: create_object_visitor.hpp:266
bool visit_nil()
Definition: create_object_visitor.hpp:69
msgpack::zone & zone()
Definition: create_object_visitor.hpp:64
msgpack::zone * m_zone
Definition: create_object_visitor.hpp:269
bool end_map_key()
Definition: create_object_visitor.hpp:241
bool referenced() const
Definition: create_object_visitor.hpp:66
bool start_array_item()
Definition: create_object_visitor.hpp:205
bool start_array(uint32_t num_elements)
Definition: create_object_visitor.hpp:182
bool visit_float32(float v)
Definition: create_object_visitor.hpp:98
unpack_reference_func m_func
Definition: create_object_visitor.hpp:264
create_object_visitor(create_object_visitor &&other)
Definition: create_object_visitor.hpp:37
bool visit_boolean(bool v)
Definition: create_object_visitor.hpp:74
bool visit_bin(const char *v, uint32_t size)
Definition: create_object_visitor.hpp:134
bool start_map_value()
Definition: create_object_visitor.hpp:245
create_object_visitor(unpack_reference_func f, void *user_data, unpack_limit const &limit)
Definition: create_object_visitor.hpp:30
void parse_error(size_t, size_t)
Definition: create_object_visitor.hpp:256
bool start_map(uint32_t num_kv_pairs)
Definition: create_object_visitor.hpp:216
void * m_user_data
Definition: create_object_visitor.hpp:265
Definition: unpack_decl.hpp:87
std::size_t bin() const
Definition: unpack_decl.hpp:105
std::size_t str() const
Definition: unpack_decl.hpp:104
std::size_t map() const
Definition: unpack_decl.hpp:103
std::size_t depth() const
Definition: unpack_decl.hpp:107
std::size_t array() const
Definition: unpack_decl.hpp:102
std::size_t ext() const
Definition: unpack_decl.hpp:106
Definition: cpp03_zone.hpp:31
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
@ FLOAT64
Definition: object_fwd_decl.hpp:33
@ BOOLEAN
Definition: object_fwd_decl.hpp:29
@ MAP
Definition: object_fwd_decl.hpp:41
@ NIL
Definition: object_fwd_decl.hpp:28
@ STR
Definition: object_fwd_decl.hpp:38
@ ARRAY
Definition: object_fwd_decl.hpp:40
@ BIN
Definition: object_fwd_decl.hpp:39
@ POSITIVE_INTEGER
Definition: object_fwd_decl.hpp:30
@ NEGATIVE_INTEGER
Definition: object_fwd_decl.hpp:31
@ FLOAT32
Definition: object_fwd_decl.hpp:32
Definition: adaptor_base.hpp:15
bool(* unpack_reference_func)(msgpack::type::object_type type, std::size_t size, void *user_data)
The type of reference or copy judging function.
Definition: unpack_decl.hpp:74
Definition: unpack_exception.hpp:61
Definition: unpack_exception.hpp:88
Definition: unpack_exception.hpp:106
Definition: unpack_exception.hpp:97
Definition: unpack_exception.hpp:43
Definition: unpack_exception.hpp:70
uint32_t size
Definition: object_fwd.hpp:23
msgpack::object * ptr
Definition: object_fwd.hpp:24
uint32_t size
Definition: object_fwd.hpp:38
const char * ptr
Definition: object_fwd.hpp:39
const char * ptr
Definition: object_fwd.hpp:46
uint32_t size
Definition: object_fwd.hpp:45
Definition: object.hpp:30
uint32_t size
Definition: object_fwd.hpp:28
msgpack::object_kv * ptr
Definition: object_fwd.hpp:29
const char * ptr
Definition: object_fwd.hpp:34
uint32_t size
Definition: object_fwd.hpp:33
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
Definition: unpack_exception.hpp:34
Definition: unpack_exception.hpp:79
bool boolean
Definition: object_fwd.hpp:77
msgpack::object_array array
Definition: object_fwd.hpp:85
msgpack::object_ext ext
Definition: object_fwd.hpp:89
msgpack::object_str str
Definition: object_fwd.hpp:87
uint64_t u64
Definition: object_fwd.hpp:78
int64_t i64
Definition: object_fwd.hpp:79
msgpack::object_bin bin
Definition: object_fwd.hpp:88
double f64
Definition: object_fwd.hpp:84
msgpack::object_map map
Definition: object_fwd.hpp:86
#define MSGPACK_EMBED_STACK_SIZE
Definition: unpack_define.hpp:16
#define MSGPACK_NULLPTR
Definition: cpp_config_decl.hpp:85
#define MSGPACK_ZONE_ALIGNOF(type)
Definition: cpp03_zone_decl.hpp:30
#define MSGPACK_API_VERSION_NAMESPACE(ns)
Definition: versioning.hpp:66