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