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