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