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_float(double v) {
96  msgpack::object* obj = m_stack.back();
98  obj->via.f64 = v;
99  return true;
100  }
101  bool visit_str(const char* v, uint32_t size) {
102  if (size > m_limit.str()) throw msgpack::str_size_overflow("str size overflow");
103  msgpack::object* obj = m_stack.back();
104  obj->type = msgpack::type::STR;
105  if (m_func && m_func(obj->type, size, m_user_data)) {
106  obj->via.str.ptr = v;
107  set_referenced(true);
108  }
109  else {
110  char* tmp = static_cast<char*>(zone().allocate_align(size));
111  std::memcpy(tmp, v, size);
112  obj->via.str.ptr = tmp;
113  }
114  obj->via.str.size = size;
115  return true;
116  }
117  bool visit_bin(const char* v, uint32_t size) {
118  if (size > m_limit.bin()) throw msgpack::bin_size_overflow("bin size overflow");
119  msgpack::object* obj = m_stack.back();
120  obj->type = msgpack::type::BIN;
121  if (m_func && m_func(obj->type, size, m_user_data)) {
122  obj->via.bin.ptr = v;
123  set_referenced(true);
124  }
125  else {
126  char* tmp = static_cast<char*>(zone().allocate_align(size));
127  std::memcpy(tmp, v, size);
128  obj->via.bin.ptr = tmp;
129  }
130  obj->via.bin.size = size;
131  return true;
132  }
133  bool visit_ext(const char* v, uint32_t size) {
134  if (size > m_limit.ext()) throw msgpack::ext_size_overflow("ext size overflow");
135  msgpack::object* obj = m_stack.back();
136  obj->type = msgpack::type::EXT;
137  if (m_func && m_func(obj->type, size, m_user_data)) {
138  obj->via.ext.ptr = v;
139  set_referenced(true);
140  }
141  else {
142  char* tmp = static_cast<char*>(zone().allocate_align(size));
143  std::memcpy(tmp, v, size);
144  obj->via.ext.ptr = tmp;
145  }
146  obj->via.ext.size = static_cast<uint32_t>(size - 1);
147  return true;
148  }
149  bool start_array(uint32_t num_elements) {
150  if (num_elements > m_limit.array()) throw msgpack::array_size_overflow("array size overflow");
151  if (m_stack.size() > m_limit.depth()) throw msgpack::depth_size_overflow("depth size overflow");
152  msgpack::object* obj = m_stack.back();
153  obj->type = msgpack::type::ARRAY;
154  obj->via.array.size = num_elements;
155  if (num_elements == 0) {
156  obj->via.array.ptr = MSGPACK_NULLPTR;
157  }
158  else {
159  size_t size = num_elements*sizeof(msgpack::object);
160  if (size / sizeof(msgpack::object) != num_elements) {
161  throw msgpack::array_size_overflow("array size overflow");
162  }
163  obj->via.array.ptr =
164  static_cast<msgpack::object*>(m_zone->allocate_align(size));
165  }
166  m_stack.push_back(obj->via.array.ptr);
167  return true;
168  }
170  return true;
171  }
172  bool end_array_item() {
173  ++m_stack.back();
174  return true;
175  }
176  bool end_array() {
177  m_stack.pop_back();
178  return true;
179  }
180  bool start_map(uint32_t num_kv_pairs) {
181  if (num_kv_pairs > m_limit.map()) throw msgpack::map_size_overflow("map size overflow");
182  if (m_stack.size() > m_limit.depth()) throw msgpack::depth_size_overflow("depth size overflow");
183  msgpack::object* obj = m_stack.back();
184  obj->type = msgpack::type::MAP;
185  obj->via.map.size = num_kv_pairs;
186  if (num_kv_pairs == 0) {
187  obj->via.map.ptr = MSGPACK_NULLPTR;
188  }
189  else {
190  size_t size = num_kv_pairs*sizeof(msgpack::object_kv);
191  if (size / sizeof(msgpack::object_kv) != num_kv_pairs) {
192  throw msgpack::map_size_overflow("map size overflow");
193  }
194  obj->via.map.ptr =
195  static_cast<msgpack::object_kv*>(m_zone->allocate_align(size));
196  }
197  m_stack.push_back(reinterpret_cast<msgpack::object*>(obj->via.map.ptr));
198  return true;
199  }
200  bool start_map_key() {
201  return true;
202  }
203  bool end_map_key() {
204  ++m_stack.back();
205  return true;
206  }
208  return true;
209  }
210  bool end_map_value() {
211  ++m_stack.back();
212  return true;
213  }
214  bool end_map() {
215  m_stack.pop_back();
216  return true;
217  }
218  void parse_error(size_t /*parsed_offset*/, size_t /*error_offset*/) {
219  throw msgpack::parse_error("parse error");
220  }
221  void insufficient_bytes(size_t /*parsed_offset*/, size_t /*error_offset*/) {
222  throw msgpack::insufficient_bytes("insufficient bytes");
223  }
224 private:
225 public:
227  void* m_user_data;
230  std::vector<msgpack::object*> m_stack;
233 };
234 
235 } // detail
236 
238 } // MSGPACK_API_VERSION_NAMESPACE(v2)
240 
241 } // namespace msgpack
242 
243 #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:133
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:236
bool visit_bin(const char *v, uint32_t size)
Definition: create_object_visitor.hpp:117
msgpack::zone & zone()
Definition: create_object_visitor.hpp:61
void set_zone(msgpack::zone &zone)
Definition: create_object_visitor.hpp:62
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:214
union_type via
Definition: object_fwd.hpp:93
bool end_map_value()
Definition: create_object_visitor.hpp:210
bool start_array(uint32_t num_elements)
Definition: create_object_visitor.hpp:149
bool visit_boolean(bool v)
Definition: create_object_visitor.hpp:71
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:180
Definition: unpack_exception.hpp:106
void init()
Definition: create_object_visitor.hpp:51
unpack_limit m_limit
Definition: create_object_visitor.hpp:228
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:60
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:218
bool referenced() const
Definition: create_object_visitor.hpp:63
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:176
create_object_visitor(create_object_visitor &&other)
Definition: create_object_visitor.hpp:34
Definition: object_fwd_decl.hpp:35
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:232
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:169
Definition: unpack_exception.hpp:88
uint32_t size
Definition: object_fwd.hpp:45
msgpack::zone * m_zone
Definition: create_object_visitor.hpp:231
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:207
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:27
bool start_map_key()
Definition: create_object_visitor.hpp:200
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:101
#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:229
uint32_t size
Definition: object_fwd.hpp:28
Definition: object_fwd_decl.hpp:42
std::vector< msgpack::object * > m_stack
Definition: create_object_visitor.hpp:230
uint32_t size
Definition: object_fwd.hpp:33
unpack_reference_func m_func
Definition: create_object_visitor.hpp:226
bool visit_float(double v)
Definition: create_object_visitor.hpp:95
bool end_array_item()
Definition: create_object_visitor.hpp:172
bool end_map_key()
Definition: create_object_visitor.hpp:203
#define MSGPACK_NULLPTR
Definition: cpp_config_decl.hpp:35
T & move(T &t)
msgpack::object_ext ext
Definition: object_fwd.hpp:89
msgpack::object const & data() const
Definition: create_object_visitor.hpp:56
void * m_user_data
Definition: create_object_visitor.hpp:227
Definition: create_object_visitor.hpp:25
std::size_t depth() const
Definition: unpack_decl.hpp:107
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:221