/src/msgpack-c/include/msgpack/v1/object.hpp
Line | Count | Source (jump to first uncovered line) |
1 | | // |
2 | | // MessagePack for C++ static resolution routine |
3 | | // |
4 | | // Copyright (C) 2008-2014 FURUHASHI Sadayuki and 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_V1_OBJECT_HPP |
11 | | #define MSGPACK_V1_OBJECT_HPP |
12 | | |
13 | | #include "msgpack/object_decl.hpp" |
14 | | #include "msgpack/adaptor/check_container_size.hpp" |
15 | | |
16 | | #include <cstring> |
17 | | #include <stdexcept> |
18 | | #include <typeinfo> |
19 | | #include <limits> |
20 | | #include <ostream> |
21 | | #include <typeinfo> |
22 | | #include <iomanip> |
23 | | |
24 | | namespace msgpack { |
25 | | |
26 | | /// @cond |
27 | | MSGPACK_API_VERSION_NAMESPACE(v1) { |
28 | | /// @endcond |
29 | | |
30 | | struct object_kv { |
31 | | msgpack::object key; |
32 | | msgpack::object val; |
33 | | }; |
34 | | |
35 | | struct object::with_zone : msgpack::object { |
36 | 0 | with_zone(msgpack::zone& z) : zone(z) { } |
37 | | msgpack::zone& zone; |
38 | | private: |
39 | | with_zone(); |
40 | | }; |
41 | | |
42 | | |
43 | | /// The class holds object and zone |
44 | | class object_handle { |
45 | | public: |
46 | | /// Constructor that creates nil object and null zone. |
47 | 0 | object_handle() {} |
48 | | |
49 | | /// Constructor that creates an object_handle holding object `obj` and zone `z`. |
50 | | /** |
51 | | * @param obj object |
52 | | * @param z zone |
53 | | */ |
54 | | object_handle( |
55 | | msgpack::object const& obj, |
56 | | #if defined(MSGPACK_USE_CPP03) |
57 | | msgpack::unique_ptr<msgpack::zone> z |
58 | | #else // defined(MSGPACK_USE_CPP03) |
59 | | msgpack::unique_ptr<msgpack::zone>&& z |
60 | | #endif // defined(MSGPACK_USE_CPP03) |
61 | | ) : |
62 | 1.19k | m_obj(obj), m_zone(msgpack::move(z)) { } |
63 | | |
64 | | void set(msgpack::object const& obj) |
65 | 0 | { m_obj = obj; } |
66 | | |
67 | | /// Get object reference |
68 | | /** |
69 | | * @return object |
70 | | */ |
71 | | const msgpack::object& get() const |
72 | 1.19k | { return m_obj; } |
73 | | |
74 | | /** |
75 | | * @return object (to mimic smart pointers). |
76 | | */ |
77 | | const msgpack::object& operator*() const |
78 | 0 | { return get(); } |
79 | | |
80 | | /** |
81 | | * @return the address of the object (to mimic smart pointers). |
82 | | */ |
83 | | const msgpack::object* operator->() const |
84 | 0 | { return &get(); } |
85 | | |
86 | | /// Get unique_ptr reference of zone. |
87 | | /** |
88 | | * @return unique_ptr reference of zone |
89 | | */ |
90 | | msgpack::unique_ptr<msgpack::zone>& zone() |
91 | 0 | { return m_zone; } |
92 | | |
93 | | /// Get unique_ptr const reference of zone. |
94 | | /** |
95 | | * @return unique_ptr const reference of zone |
96 | | */ |
97 | | const msgpack::unique_ptr<msgpack::zone>& zone() const |
98 | 0 | { return m_zone; } |
99 | | |
100 | | #if defined(MSGPACK_USE_CPP03) |
101 | | struct object_handle_ref { |
102 | | object_handle_ref(object_handle* oh):m_oh(oh) {} |
103 | | object_handle* m_oh; |
104 | | }; |
105 | | |
106 | | object_handle(object_handle& other): |
107 | | m_obj(other.m_obj), |
108 | | m_zone(msgpack::move(other.m_zone)) { |
109 | | } |
110 | | |
111 | | object_handle(object_handle_ref ref): |
112 | | m_obj(ref.m_oh->m_obj), |
113 | | m_zone(msgpack::move(ref.m_oh->m_zone)) { |
114 | | } |
115 | | |
116 | | object_handle& operator=(object_handle& other) { |
117 | | m_obj = other.m_obj; |
118 | | m_zone = msgpack::move(other.m_zone); |
119 | | return *this; |
120 | | } |
121 | | |
122 | | object_handle& operator=(object_handle_ref ref) { |
123 | | m_obj = ref.m_oh->m_obj; |
124 | | m_zone = msgpack::move(ref.m_oh->m_zone); |
125 | | return *this; |
126 | | } |
127 | | |
128 | | operator object_handle_ref() { |
129 | | return object_handle_ref(this); |
130 | | } |
131 | | #endif // defined(MSGPACK_USE_CPP03) |
132 | | |
133 | | private: |
134 | | msgpack::object m_obj; |
135 | | msgpack::unique_ptr<msgpack::zone> m_zone; |
136 | | }; |
137 | | |
138 | | namespace detail { |
139 | | |
140 | | template <std::size_t N> |
141 | | inline std::size_t add_ext_type_size(std::size_t size) { |
142 | | return size + 1; |
143 | | } |
144 | | |
145 | | template <> |
146 | 0 | inline std::size_t add_ext_type_size<4>(std::size_t size) { |
147 | 0 | return size == 0xffffffff ? size : size + 1; |
148 | 0 | } |
149 | | |
150 | | } // namespace detail |
151 | | class object_parser { |
152 | | private: |
153 | | enum next_ret { |
154 | | cont, |
155 | | finish, |
156 | | abort |
157 | | }; |
158 | | struct elem { |
159 | | elem(msgpack::object const* p, std::size_t r) |
160 | 83.8k | : rest(r), is_map(false), is_key(false) { |
161 | 83.8k | as.obj_ptr = p; |
162 | 83.8k | } |
163 | | |
164 | | elem(msgpack::object_kv const* p, std::size_t r) |
165 | 128k | : rest(r), is_map(true), is_key(true) { |
166 | 128k | as.kv_ptr = p; |
167 | 128k | } |
168 | | |
169 | 1.27M | msgpack::object const& get() const { |
170 | 1.27M | if (is_map) { |
171 | 873k | if (is_key) { |
172 | 436k | return as.kv_ptr->key; |
173 | 436k | } |
174 | 436k | else { |
175 | 436k | return as.kv_ptr->val; |
176 | 436k | } |
177 | 873k | } |
178 | 396k | else { |
179 | 396k | return *as.obj_ptr; |
180 | 396k | } |
181 | 1.27M | } |
182 | | |
183 | | template <typename Visitor> |
184 | 1.29M | next_ret next(Visitor& v) { |
185 | 1.29M | if (rest == 0) { |
186 | 28.1k | if (is_map) { |
187 | 12.8k | if (!v.end_map()) return abort; |
188 | 12.8k | } |
189 | 15.2k | else { |
190 | 15.2k | if (!v.end_array()) return abort; |
191 | 15.2k | } |
192 | 28.1k | return finish; |
193 | 28.1k | } |
194 | 1.27M | else { |
195 | 1.27M | if (is_map) { |
196 | 873k | if (is_key) { |
197 | 436k | if (!v.end_map_key()) return abort; |
198 | 436k | if (!v.start_map_value()) return abort; |
199 | 436k | is_key = false; |
200 | 436k | } |
201 | 436k | else { |
202 | 436k | if (!v.end_map_value()) return abort; |
203 | 436k | --rest; |
204 | 436k | if (rest == 0) { |
205 | 115k | if (!v.end_map()) return abort; |
206 | 115k | return finish; |
207 | 115k | } |
208 | 321k | if (!v.start_map_key()) return abort; |
209 | 321k | ++as.kv_ptr; |
210 | 321k | is_key = true; |
211 | 321k | } |
212 | 873k | } |
213 | 396k | else { |
214 | 396k | if (!v.end_array_item()) return abort; |
215 | 396k | --rest; |
216 | 396k | if (rest == 0) { |
217 | 68.5k | if (!v.end_array()) return abort; |
218 | 68.5k | return finish; |
219 | 68.5k | } |
220 | 328k | if (!v.start_array_item()) return abort; |
221 | 328k | ++as.obj_ptr; |
222 | 328k | } |
223 | 1.08M | return cont; |
224 | 1.27M | } |
225 | 1.29M | } msgpack::v1::object_parser::next_ret msgpack::v1::object_parser::elem::next<msgpack::v1::object_pack_visitor<msgpack::v1::sbuffer> >(msgpack::v1::object_pack_visitor<msgpack::v1::sbuffer>&) Line | Count | Source | 184 | 1.29M | next_ret next(Visitor& v) { | 185 | 1.29M | if (rest == 0) { | 186 | 28.1k | if (is_map) { | 187 | 12.8k | if (!v.end_map()) return abort; | 188 | 12.8k | } | 189 | 15.2k | else { | 190 | 15.2k | if (!v.end_array()) return abort; | 191 | 15.2k | } | 192 | 28.1k | return finish; | 193 | 28.1k | } | 194 | 1.27M | else { | 195 | 1.27M | if (is_map) { | 196 | 873k | if (is_key) { | 197 | 436k | if (!v.end_map_key()) return abort; | 198 | 436k | if (!v.start_map_value()) return abort; | 199 | 436k | is_key = false; | 200 | 436k | } | 201 | 436k | else { | 202 | 436k | if (!v.end_map_value()) return abort; | 203 | 436k | --rest; | 204 | 436k | if (rest == 0) { | 205 | 115k | if (!v.end_map()) return abort; | 206 | 115k | return finish; | 207 | 115k | } | 208 | 321k | if (!v.start_map_key()) return abort; | 209 | 321k | ++as.kv_ptr; | 210 | 321k | is_key = true; | 211 | 321k | } | 212 | 873k | } | 213 | 396k | else { | 214 | 396k | if (!v.end_array_item()) return abort; | 215 | 396k | --rest; | 216 | 396k | if (rest == 0) { | 217 | 68.5k | if (!v.end_array()) return abort; | 218 | 68.5k | return finish; | 219 | 68.5k | } | 220 | 328k | if (!v.start_array_item()) return abort; | 221 | 328k | ++as.obj_ptr; | 222 | 328k | } | 223 | 1.08M | return cont; | 224 | 1.27M | } | 225 | 1.29M | } |
Unexecuted instantiation: msgpack::v1::object_parser::next_ret msgpack::v1::object_parser::elem::next<msgpack::v1::aligned_zone_size_visitor>(msgpack::v1::aligned_zone_size_visitor&) Unexecuted instantiation: msgpack::v1::object_parser::next_ret msgpack::v1::object_parser::elem::next<msgpack::v1::adaptor::object_with_zone<msgpack::v2::object, void>::object_with_zone_visitor>(msgpack::v1::adaptor::object_with_zone<msgpack::v2::object, void>::object_with_zone_visitor&) Unexecuted instantiation: msgpack::v1::object_parser::next_ret msgpack::v1::object_parser::elem::next<msgpack::v1::object_equal_visitor>(msgpack::v1::object_equal_visitor&) Unexecuted instantiation: msgpack::v1::object_parser::next_ret msgpack::v1::object_parser::elem::next<msgpack::v1::object_stringize_visitor>(msgpack::v1::object_stringize_visitor&) |
226 | | |
227 | | union { |
228 | | msgpack::object const* obj_ptr; |
229 | | msgpack::object_kv const* kv_ptr; |
230 | | } as; |
231 | | std::size_t rest; |
232 | | bool is_map; |
233 | | bool is_key; |
234 | | }; |
235 | | public: |
236 | 1.19k | explicit object_parser(msgpack::object const& obj):m_current(&obj) {} |
237 | | template <typename Visitor> |
238 | 1.19k | void parse(Visitor& v) { |
239 | 1.27M | while (true) { |
240 | 1.27M | bool start_collection = false; |
241 | 1.27M | switch(m_current->type) { |
242 | 3.06k | case msgpack::type::NIL: |
243 | 3.06k | if (!v.visit_nil()) return; |
244 | 3.06k | break; |
245 | 5.96k | case msgpack::type::BOOLEAN: |
246 | 5.96k | if (!v.visit_boolean(m_current->via.boolean)) return; |
247 | 5.96k | break; |
248 | 431k | case msgpack::type::POSITIVE_INTEGER: |
249 | 431k | if (!v.visit_positive_integer(m_current->via.u64)) return; |
250 | 431k | break; |
251 | 431k | case msgpack::type::NEGATIVE_INTEGER: |
252 | 105k | if (!v.visit_negative_integer(m_current->via.i64)) return; |
253 | 105k | break; |
254 | 461k | case msgpack::type::FLOAT32: |
255 | 461k | if (!v.visit_float32(static_cast<float>(m_current->via.f64))) return; |
256 | 461k | break; |
257 | 461k | case msgpack::type::FLOAT64: |
258 | 17.3k | if (!v.visit_float64(m_current->via.f64)) return; |
259 | 17.3k | break; |
260 | 17.3k | case msgpack::type::STR: |
261 | 14.7k | if (!v.visit_str(m_current->via.str.ptr, m_current->via.str.size)) return; |
262 | 14.7k | break; |
263 | 14.7k | case msgpack::type::BIN: |
264 | 2.35k | if (!v.visit_bin(m_current->via.bin.ptr, m_current->via.bin.size)) return; |
265 | 2.35k | break; |
266 | 17.4k | case msgpack::type::EXT: |
267 | 17.4k | msgpack::detail::check_container_size<sizeof(std::size_t)>(m_current->via.ext.size); |
268 | 17.4k | if (!v.visit_ext(m_current->via.ext.ptr, m_current->via.ext.size + 1)) return; |
269 | 17.4k | break; |
270 | 83.8k | case msgpack::type::ARRAY: |
271 | 83.8k | if (!v.start_array(m_current->via.array.size)) return; |
272 | 83.8k | m_ctx.push_back(elem(m_current->via.array.ptr, m_current->via.array.size)); |
273 | 83.8k | start_collection = m_current->via.array.size != 0; |
274 | 83.8k | if (start_collection) { |
275 | 68.5k | if (!v.start_array_item()) return; |
276 | 68.5k | } |
277 | 83.8k | break; |
278 | 128k | case msgpack::type::MAP: |
279 | 128k | if (!v.start_map(m_current->via.map.size)) return; |
280 | 128k | m_ctx.push_back(elem(m_current->via.map.ptr, m_current->via.map.size)); |
281 | 128k | start_collection = m_current->via.map.size != 0; |
282 | 128k | if (start_collection) { |
283 | 115k | if (!v.start_map_key()) return; |
284 | 115k | } |
285 | 128k | break; |
286 | 128k | default: |
287 | 0 | throw msgpack::type_error(); |
288 | 0 | break; |
289 | 1.27M | } |
290 | 1.27M | if (m_ctx.empty()) return; |
291 | 1.27M | if (!start_collection) { |
292 | 1.29M | while (true) { |
293 | 1.29M | next_ret r = m_ctx.back().next(v); |
294 | 1.29M | if (r == finish) { |
295 | 211k | m_ctx.pop_back(); |
296 | 211k | if (m_ctx.empty()) return; |
297 | 211k | } |
298 | 1.08M | else if (r == cont) { |
299 | 1.08M | break; |
300 | 1.08M | } |
301 | 0 | else { |
302 | | // abort |
303 | 0 | return; |
304 | 0 | } |
305 | 1.29M | } |
306 | 1.08M | } |
307 | 1.27M | m_current = &m_ctx.back().get(); |
308 | 1.27M | } |
309 | 1.19k | } void msgpack::v1::object_parser::parse<msgpack::v1::object_pack_visitor<msgpack::v1::sbuffer> >(msgpack::v1::object_pack_visitor<msgpack::v1::sbuffer>&) Line | Count | Source | 238 | 1.19k | void parse(Visitor& v) { | 239 | 1.27M | while (true) { | 240 | 1.27M | bool start_collection = false; | 241 | 1.27M | switch(m_current->type) { | 242 | 3.06k | case msgpack::type::NIL: | 243 | 3.06k | if (!v.visit_nil()) return; | 244 | 3.06k | break; | 245 | 5.96k | case msgpack::type::BOOLEAN: | 246 | 5.96k | if (!v.visit_boolean(m_current->via.boolean)) return; | 247 | 5.96k | break; | 248 | 431k | case msgpack::type::POSITIVE_INTEGER: | 249 | 431k | if (!v.visit_positive_integer(m_current->via.u64)) return; | 250 | 431k | break; | 251 | 431k | case msgpack::type::NEGATIVE_INTEGER: | 252 | 105k | if (!v.visit_negative_integer(m_current->via.i64)) return; | 253 | 105k | break; | 254 | 461k | case msgpack::type::FLOAT32: | 255 | 461k | if (!v.visit_float32(static_cast<float>(m_current->via.f64))) return; | 256 | 461k | break; | 257 | 461k | case msgpack::type::FLOAT64: | 258 | 17.3k | if (!v.visit_float64(m_current->via.f64)) return; | 259 | 17.3k | break; | 260 | 17.3k | case msgpack::type::STR: | 261 | 14.7k | if (!v.visit_str(m_current->via.str.ptr, m_current->via.str.size)) return; | 262 | 14.7k | break; | 263 | 14.7k | case msgpack::type::BIN: | 264 | 2.35k | if (!v.visit_bin(m_current->via.bin.ptr, m_current->via.bin.size)) return; | 265 | 2.35k | break; | 266 | 17.4k | case msgpack::type::EXT: | 267 | 17.4k | msgpack::detail::check_container_size<sizeof(std::size_t)>(m_current->via.ext.size); | 268 | 17.4k | if (!v.visit_ext(m_current->via.ext.ptr, m_current->via.ext.size + 1)) return; | 269 | 17.4k | break; | 270 | 83.8k | case msgpack::type::ARRAY: | 271 | 83.8k | if (!v.start_array(m_current->via.array.size)) return; | 272 | 83.8k | m_ctx.push_back(elem(m_current->via.array.ptr, m_current->via.array.size)); | 273 | 83.8k | start_collection = m_current->via.array.size != 0; | 274 | 83.8k | if (start_collection) { | 275 | 68.5k | if (!v.start_array_item()) return; | 276 | 68.5k | } | 277 | 83.8k | break; | 278 | 128k | case msgpack::type::MAP: | 279 | 128k | if (!v.start_map(m_current->via.map.size)) return; | 280 | 128k | m_ctx.push_back(elem(m_current->via.map.ptr, m_current->via.map.size)); | 281 | 128k | start_collection = m_current->via.map.size != 0; | 282 | 128k | if (start_collection) { | 283 | 115k | if (!v.start_map_key()) return; | 284 | 115k | } | 285 | 128k | break; | 286 | 128k | default: | 287 | 0 | throw msgpack::type_error(); | 288 | 0 | break; | 289 | 1.27M | } | 290 | 1.27M | if (m_ctx.empty()) return; | 291 | 1.27M | if (!start_collection) { | 292 | 1.29M | while (true) { | 293 | 1.29M | next_ret r = m_ctx.back().next(v); | 294 | 1.29M | if (r == finish) { | 295 | 211k | m_ctx.pop_back(); | 296 | 211k | if (m_ctx.empty()) return; | 297 | 211k | } | 298 | 1.08M | else if (r == cont) { | 299 | 1.08M | break; | 300 | 1.08M | } | 301 | 0 | else { | 302 | | // abort | 303 | 0 | return; | 304 | 0 | } | 305 | 1.29M | } | 306 | 1.08M | } | 307 | 1.27M | m_current = &m_ctx.back().get(); | 308 | 1.27M | } | 309 | 1.19k | } |
Unexecuted instantiation: void msgpack::v1::object_parser::parse<msgpack::v1::aligned_zone_size_visitor>(msgpack::v1::aligned_zone_size_visitor&) Unexecuted instantiation: void msgpack::v1::object_parser::parse<msgpack::v1::adaptor::object_with_zone<msgpack::v2::object, void>::object_with_zone_visitor>(msgpack::v1::adaptor::object_with_zone<msgpack::v2::object, void>::object_with_zone_visitor&) Unexecuted instantiation: void msgpack::v1::object_parser::parse<msgpack::v1::object_equal_visitor>(msgpack::v1::object_equal_visitor&) Unexecuted instantiation: void msgpack::v1::object_parser::parse<msgpack::v1::object_stringize_visitor>(msgpack::v1::object_stringize_visitor&) |
310 | | private: |
311 | | msgpack::object const* m_current; |
312 | | std::vector<elem> m_ctx; |
313 | | }; |
314 | | |
315 | | template <typename Stream> |
316 | | struct object_pack_visitor { |
317 | | explicit object_pack_visitor(msgpack::packer<Stream>& pk) |
318 | 1.19k | :m_packer(pk) {} |
319 | 3.06k | bool visit_nil() { |
320 | 3.06k | m_packer.pack_nil(); |
321 | 3.06k | return true; |
322 | 3.06k | } |
323 | 5.96k | bool visit_boolean(bool v) { |
324 | 5.96k | if (v) m_packer.pack_true(); |
325 | 1.18k | else m_packer.pack_false(); |
326 | 5.96k | return true; |
327 | 5.96k | } |
328 | 431k | bool visit_positive_integer(uint64_t v) { |
329 | 431k | m_packer.pack_uint64(v); |
330 | 431k | return true; |
331 | 431k | } |
332 | 105k | bool visit_negative_integer(int64_t v) { |
333 | 105k | m_packer.pack_int64(v); |
334 | 105k | return true; |
335 | 105k | } |
336 | 461k | bool visit_float32(float v) { |
337 | 461k | m_packer.pack_float(v); |
338 | 461k | return true; |
339 | 461k | } |
340 | 17.3k | bool visit_float64(double v) { |
341 | 17.3k | m_packer.pack_double(v); |
342 | 17.3k | return true; |
343 | 17.3k | } |
344 | 14.7k | bool visit_str(const char* v, uint32_t size) { |
345 | 14.7k | m_packer.pack_str(size); |
346 | 14.7k | m_packer.pack_str_body(v, size); |
347 | 14.7k | return true; |
348 | 14.7k | } |
349 | 2.35k | bool visit_bin(const char* v, uint32_t size) { |
350 | 2.35k | m_packer.pack_bin(size); |
351 | 2.35k | m_packer.pack_bin_body(v, size); |
352 | 2.35k | return true; |
353 | 2.35k | } |
354 | 17.4k | bool visit_ext(const char* v, uint32_t size) { |
355 | 17.4k | m_packer.pack_ext(size - 1, static_cast<int8_t>(*v)); |
356 | 17.4k | m_packer.pack_ext_body(v + 1, size - 1); |
357 | 17.4k | return true; |
358 | 17.4k | } |
359 | 83.8k | bool start_array(uint32_t num_elements) { |
360 | 83.8k | m_packer.pack_array(num_elements); |
361 | 83.8k | return true; |
362 | 83.8k | } |
363 | 396k | bool start_array_item() { |
364 | 396k | return true; |
365 | 396k | } |
366 | 396k | bool end_array_item() { |
367 | 396k | return true; |
368 | 396k | } |
369 | 83.8k | bool end_array() { |
370 | 83.8k | return true; |
371 | 83.8k | } |
372 | 128k | bool start_map(uint32_t num_kv_pairs) { |
373 | 128k | m_packer.pack_map(num_kv_pairs); |
374 | 128k | return true; |
375 | 128k | } |
376 | 436k | bool start_map_key() { |
377 | 436k | return true; |
378 | 436k | } |
379 | 436k | bool end_map_key() { |
380 | 436k | return true; |
381 | 436k | } |
382 | 436k | bool start_map_value() { |
383 | 436k | return true; |
384 | 436k | } |
385 | 436k | bool end_map_value() { |
386 | 436k | return true; |
387 | 436k | } |
388 | 128k | bool end_map() { |
389 | 128k | return true; |
390 | 128k | } |
391 | | private: |
392 | | msgpack::packer<Stream>& m_packer; |
393 | | }; |
394 | | |
395 | | |
396 | | struct object_stringize_visitor { |
397 | | explicit object_stringize_visitor(std::ostream& os) |
398 | 0 | :m_os(os) {} |
399 | 0 | bool visit_nil() { |
400 | 0 | m_os << "null"; |
401 | 0 | return true; |
402 | 0 | } |
403 | 0 | bool visit_boolean(bool v) { |
404 | 0 | if (v) m_os << "true"; |
405 | 0 | else m_os << "false"; |
406 | 0 | return true; |
407 | 0 | } |
408 | 0 | bool visit_positive_integer(uint64_t v) { |
409 | 0 | m_os << v; |
410 | 0 | return true; |
411 | 0 | } |
412 | 0 | bool visit_negative_integer(int64_t v) { |
413 | 0 | m_os << v; |
414 | 0 | return true; |
415 | 0 | } |
416 | 0 | bool visit_float32(float v) { |
417 | 0 | m_os << v; |
418 | 0 | return true; |
419 | 0 | } |
420 | 0 | bool visit_float64(double v) { |
421 | 0 | m_os << v; |
422 | 0 | return true; |
423 | 0 | } |
424 | 0 | bool visit_str(const char* v, uint32_t size) { |
425 | 0 | m_os << '"'; |
426 | 0 | for (uint32_t i = 0; i < size; ++i) { |
427 | 0 | char c = v[i]; |
428 | 0 | switch (c) { |
429 | 0 | case '\\': |
430 | 0 | m_os << "\\\\"; |
431 | 0 | break; |
432 | 0 | case '"': |
433 | 0 | m_os << "\\\""; |
434 | 0 | break; |
435 | 0 | case '/': |
436 | 0 | m_os << "\\/"; |
437 | 0 | break; |
438 | 0 | case '\b': |
439 | 0 | m_os << "\\b"; |
440 | 0 | break; |
441 | 0 | case '\f': |
442 | 0 | m_os << "\\f"; |
443 | 0 | break; |
444 | 0 | case '\n': |
445 | 0 | m_os << "\\n"; |
446 | 0 | break; |
447 | 0 | case '\r': |
448 | 0 | m_os << "\\r"; |
449 | 0 | break; |
450 | 0 | case '\t': |
451 | 0 | m_os << "\\t"; |
452 | 0 | break; |
453 | 0 | default: { |
454 | 0 | unsigned int code = static_cast<unsigned int>(c); |
455 | 0 | if (code < 0x20 || code == 0x7f) { |
456 | 0 | std::ios::fmtflags flags(m_os.flags()); |
457 | 0 | m_os << "\\u" << std::hex << std::setw(4) << std::setfill('0') << (code & 0xff); |
458 | 0 | m_os.flags(flags); |
459 | 0 | } |
460 | 0 | else { |
461 | 0 | m_os << c; |
462 | 0 | } |
463 | 0 | } break; |
464 | 0 | } |
465 | 0 | } |
466 | 0 | m_os << '"'; |
467 | 0 | return true; |
468 | 0 | } |
469 | 0 | bool visit_bin(const char* /*v*/, uint32_t size) { |
470 | 0 | m_os << "\"BIN(size:" << size << ")\""; |
471 | 0 | return true; |
472 | 0 | } |
473 | 0 | bool visit_ext(const char* v, uint32_t size) { |
474 | 0 | if (size == 0) { |
475 | 0 | m_os << "\"EXT(size:0)\""; |
476 | 0 | } |
477 | 0 | else { |
478 | 0 | m_os << "\"EXT(type:" << static_cast<int>(v[0]) << ",size:" << size - 1 << ")\""; |
479 | 0 | } |
480 | 0 | return true; |
481 | 0 | } |
482 | 0 | bool start_array(uint32_t num_elements) { |
483 | 0 | m_current_size.push_back(num_elements); |
484 | 0 | m_os << "["; |
485 | 0 | return true; |
486 | 0 | } |
487 | 0 | bool start_array_item() { |
488 | 0 | return true; |
489 | 0 | } |
490 | 0 | bool end_array_item() { |
491 | 0 | --m_current_size.back(); |
492 | 0 | if (m_current_size.back() != 0) { |
493 | 0 | m_os << ","; |
494 | 0 | } |
495 | 0 | return true; |
496 | 0 | } |
497 | 0 | bool end_array() { |
498 | 0 | m_current_size.pop_back(); |
499 | 0 | m_os << "]"; |
500 | 0 | return true; |
501 | 0 | } |
502 | 0 | bool start_map(uint32_t num_kv_pairs) { |
503 | 0 | m_current_size.push_back(num_kv_pairs); |
504 | 0 | m_os << "{"; |
505 | 0 | return true; |
506 | 0 | } |
507 | 0 | bool start_map_key() { |
508 | 0 | return true; |
509 | 0 | } |
510 | 0 | bool end_map_key() { |
511 | 0 | m_os << ":"; |
512 | 0 | return true; |
513 | 0 | } |
514 | 0 | bool start_map_value() { |
515 | 0 | return true; |
516 | 0 | } |
517 | 0 | bool end_map_value() { |
518 | 0 | --m_current_size.back(); |
519 | 0 | if (m_current_size.back() != 0) { |
520 | 0 | m_os << ","; |
521 | 0 | } |
522 | 0 | return true; |
523 | 0 | } |
524 | 0 | bool end_map() { |
525 | 0 | m_current_size.pop_back(); |
526 | 0 | m_os << "}"; |
527 | 0 | return true; |
528 | 0 | } |
529 | | private: |
530 | | std::ostream& m_os; |
531 | | std::vector<uint32_t> m_current_size; |
532 | | }; |
533 | | |
534 | | struct aligned_zone_size_visitor { |
535 | | explicit aligned_zone_size_visitor(std::size_t& s) |
536 | 0 | :m_size(s) {} |
537 | 0 | bool visit_nil() { |
538 | 0 | return true; |
539 | 0 | } |
540 | 0 | bool visit_boolean(bool) { |
541 | 0 | return true; |
542 | 0 | } |
543 | 0 | bool visit_positive_integer(uint64_t) { |
544 | 0 | return true; |
545 | 0 | } |
546 | 0 | bool visit_negative_integer(int64_t) { |
547 | 0 | return true; |
548 | 0 | } |
549 | 0 | bool visit_float32(float) { |
550 | 0 | return true; |
551 | 0 | } |
552 | 0 | bool visit_float64(double) { |
553 | 0 | return true; |
554 | 0 | } |
555 | 0 | bool visit_str(const char*, uint32_t size) { |
556 | 0 | m_size += msgpack::aligned_size(size, MSGPACK_ZONE_ALIGNOF(char)); |
557 | 0 | return true; |
558 | 0 | } |
559 | 0 | bool visit_bin(const char*, uint32_t size) { |
560 | 0 | m_size += msgpack::aligned_size(size, MSGPACK_ZONE_ALIGNOF(char)); |
561 | 0 | return true; |
562 | 0 | } |
563 | 0 | bool visit_ext(const char*, uint32_t size) { |
564 | 0 | m_size += msgpack::aligned_size(size, MSGPACK_ZONE_ALIGNOF(char)); |
565 | 0 | return true; |
566 | 0 | } |
567 | 0 | bool start_array(uint32_t num_elements) { |
568 | 0 | m_size += msgpack::aligned_size( |
569 | 0 | sizeof(msgpack::object) * num_elements, |
570 | 0 | MSGPACK_ZONE_ALIGNOF(msgpack::object)); |
571 | 0 | return true; |
572 | 0 | } |
573 | 0 | bool start_array_item() { |
574 | 0 | return true; |
575 | 0 | } |
576 | 0 | bool end_array_item() { |
577 | 0 | return true; |
578 | 0 | } |
579 | 0 | bool end_array() { |
580 | 0 | return true; |
581 | 0 | } |
582 | 0 | bool start_map(uint32_t num_kv_pairs) { |
583 | 0 | m_size += msgpack::aligned_size( |
584 | 0 | sizeof(msgpack::object_kv) * num_kv_pairs, |
585 | 0 | MSGPACK_ZONE_ALIGNOF(msgpack::object_kv)); |
586 | 0 | return true; |
587 | 0 | } |
588 | 0 | bool start_map_key() { |
589 | 0 | return true; |
590 | 0 | } |
591 | 0 | bool end_map_key() { |
592 | 0 | return true; |
593 | 0 | } |
594 | 0 | bool start_map_value() { |
595 | 0 | return true; |
596 | 0 | } |
597 | 0 | bool end_map_value() { |
598 | 0 | return true; |
599 | 0 | } |
600 | 0 | bool end_map() { |
601 | 0 | return true; |
602 | 0 | } |
603 | | private: |
604 | | std::size_t& m_size; |
605 | | }; |
606 | | |
607 | 0 | inline std::size_t aligned_zone_size(msgpack::object const& obj) { |
608 | 0 | std::size_t s = 0; |
609 | 0 | aligned_zone_size_visitor vis(s); |
610 | 0 | msgpack::object_parser(obj).parse(vis); |
611 | 0 | return s; |
612 | 0 | } |
613 | | |
614 | | /// clone object |
615 | | /** |
616 | | * Clone (deep copy) object. |
617 | | * The copied object is located on newly allocated zone. |
618 | | * @param obj copy source object |
619 | | * |
620 | | * @return object_handle that holds deep copied object and zone. |
621 | | */ |
622 | 0 | inline object_handle clone(msgpack::object const& obj) { |
623 | 0 | std::size_t size = msgpack::aligned_zone_size(obj); |
624 | 0 | msgpack::unique_ptr<msgpack::zone> z(size == 0 ? MSGPACK_NULLPTR : new msgpack::zone(size)); |
625 | 0 | msgpack::object newobj = z.get() ? msgpack::object(obj, *z) : obj; |
626 | 0 | return object_handle(newobj, msgpack::move(z)); |
627 | 0 | } |
628 | | |
629 | | template <typename T> |
630 | | inline object::implicit_type::operator T() { return obj.as<T>(); } |
631 | | |
632 | | namespace detail { |
633 | | template <typename Stream, typename T> |
634 | | struct packer_serializer { |
635 | | static msgpack::packer<Stream>& pack(msgpack::packer<Stream>& o, const T& v) { |
636 | | v.msgpack_pack(o); |
637 | | return o; |
638 | | } |
639 | | }; |
640 | | } // namespace detail |
641 | | |
642 | | // Adaptor functors' member functions definitions. |
643 | | template <typename T, typename Enabler> |
644 | | inline |
645 | | msgpack::object const& |
646 | | adaptor::convert<T, Enabler>::operator()(msgpack::object const& o, T& v) const { |
647 | | v.msgpack_unpack(o.convert()); |
648 | | return o; |
649 | | } |
650 | | |
651 | | template <typename T, typename Enabler> |
652 | | template <typename Stream> |
653 | | inline |
654 | | msgpack::packer<Stream>& |
655 | | adaptor::pack<T, Enabler>::operator()(msgpack::packer<Stream>& o, T const& v) const { |
656 | | return msgpack::detail::packer_serializer<Stream, T>::pack(o, v); |
657 | | } |
658 | | |
659 | | template <typename T, typename Enabler> |
660 | | inline |
661 | | void |
662 | | adaptor::object_with_zone<T, Enabler>::operator()(msgpack::object::with_zone& o, T const& v) const { |
663 | | v.msgpack_object(static_cast<msgpack::object*>(&o), o.zone); |
664 | | } |
665 | | |
666 | | // Adaptor functor specialization to object |
667 | | namespace adaptor { |
668 | | |
669 | | template <> |
670 | | struct convert<msgpack::object> { |
671 | 0 | msgpack::object const& operator()(msgpack::object const& o, msgpack::object& v) const { |
672 | 0 | v = o; |
673 | 0 | return o; |
674 | 0 | } |
675 | | }; |
676 | | |
677 | | template <> |
678 | | struct pack<msgpack::object> { |
679 | | template <typename Stream> |
680 | 1.19k | msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, msgpack::object const& v) const { |
681 | 1.19k | object_pack_visitor<Stream> vis(o); |
682 | 1.19k | msgpack::object_parser(v).parse(vis); |
683 | 1.19k | return o; |
684 | 1.19k | } |
685 | | }; |
686 | | |
687 | | template <> |
688 | | struct object_with_zone<msgpack::object> { |
689 | 0 | void operator()(msgpack::object::with_zone& o, msgpack::object const& v) const { |
690 | 0 | object_with_zone_visitor vis(o); |
691 | 0 | msgpack::object_parser(v).parse(vis); |
692 | 0 | } |
693 | | private: |
694 | | struct object_with_zone_visitor { |
695 | | explicit object_with_zone_visitor(msgpack::object::with_zone& owz) |
696 | 0 | :m_zone(owz.zone), m_ptr(&owz) { |
697 | 0 | m_objs.push_back(&owz); |
698 | 0 | } |
699 | 0 | bool visit_nil() { |
700 | 0 | m_ptr->type = msgpack::type::NIL; |
701 | 0 | return true; |
702 | 0 | } |
703 | 0 | bool visit_boolean(bool v) { |
704 | 0 | m_ptr->type = msgpack::type::BOOLEAN; |
705 | 0 | m_ptr->via.boolean = v; |
706 | 0 | return true; |
707 | 0 | } |
708 | 0 | bool visit_positive_integer(uint64_t v) { |
709 | 0 | m_ptr->type = msgpack::type::POSITIVE_INTEGER; |
710 | 0 | m_ptr->via.u64 = v; |
711 | 0 | return true; |
712 | 0 | } |
713 | 0 | bool visit_negative_integer(int64_t v) { |
714 | 0 | m_ptr->type = msgpack::type::NEGATIVE_INTEGER; |
715 | 0 | m_ptr->via.i64 = v; |
716 | 0 | return true; |
717 | 0 | } |
718 | 0 | bool visit_float32(float v) { |
719 | 0 | m_ptr->type = msgpack::type::FLOAT32; |
720 | 0 | m_ptr->via.f64 = v; |
721 | 0 | return true; |
722 | 0 | } |
723 | 0 | bool visit_float64(double v) { |
724 | 0 | m_ptr->type = msgpack::type::FLOAT64; |
725 | 0 | m_ptr->via.f64 = v; |
726 | 0 | return true; |
727 | 0 | } |
728 | 0 | bool visit_str(const char* v, uint32_t size) { |
729 | 0 | m_ptr->type = msgpack::type::STR; |
730 | 0 | m_ptr->via.str.size = size; |
731 | 0 | char* ptr = static_cast<char*>(m_zone.allocate_align(size, MSGPACK_ZONE_ALIGNOF(char))); |
732 | 0 | m_ptr->via.str.ptr = ptr; |
733 | 0 | std::memcpy(ptr, v, size); |
734 | 0 | return true; |
735 | 0 | } |
736 | 0 | bool visit_bin(const char* v, uint32_t size) { |
737 | 0 | m_ptr->type = msgpack::type::BIN; |
738 | 0 | m_ptr->via.bin.size = size; |
739 | 0 | char* ptr = static_cast<char*>(m_zone.allocate_align(size, MSGPACK_ZONE_ALIGNOF(char))); |
740 | 0 | m_ptr->via.bin.ptr = ptr; |
741 | 0 | std::memcpy(ptr, v, size); |
742 | 0 | return true; |
743 | 0 | } |
744 | 0 | bool visit_ext(const char* v, uint32_t size) { |
745 | 0 | m_ptr->type = msgpack::type::EXT; |
746 | 0 |
|
747 | 0 | // v contains type but length(size) doesn't count the type byte. |
748 | 0 | // See https://github.com/msgpack/msgpack/blob/master/spec.md#ext-format-family |
749 | 0 | m_ptr->via.ext.size = size - 1; |
750 | 0 |
|
751 | 0 | char* ptr = static_cast<char*>(m_zone.allocate_align(size, MSGPACK_ZONE_ALIGNOF(char))); |
752 | 0 | m_ptr->via.ext.ptr = ptr; |
753 | 0 | std::memcpy(ptr, v, size); |
754 | 0 | return true; |
755 | 0 | } |
756 | 0 | bool start_array(uint32_t num_elements) { |
757 | 0 | m_ptr->type = msgpack::type::ARRAY; |
758 | 0 | m_ptr->via.array.ptr = static_cast<msgpack::object*>( |
759 | 0 | m_zone.allocate_align( |
760 | 0 | sizeof(msgpack::object) * num_elements, MSGPACK_ZONE_ALIGNOF(msgpack::object))); |
761 | 0 | m_ptr->via.array.size = num_elements; |
762 | 0 | m_objs.push_back(elem(m_ptr->via.array.ptr)); |
763 | 0 | return true; |
764 | 0 | } |
765 | 0 | bool start_array_item() { |
766 | 0 | m_ptr = m_objs.back().get_item(); |
767 | 0 | return true; |
768 | 0 | } |
769 | 0 | bool end_array_item() { |
770 | 0 | ++m_objs.back().as.obj; |
771 | 0 | return true; |
772 | 0 | } |
773 | 0 | bool end_array() { |
774 | 0 | m_objs.pop_back(); |
775 | 0 | return true; |
776 | 0 | } |
777 | 0 | bool start_map(uint32_t num_kv_pairs) { |
778 | 0 | m_ptr->type = msgpack::type::MAP; |
779 | 0 | m_ptr->via.map.ptr = (msgpack::object_kv*)m_zone.allocate_align( |
780 | 0 | sizeof(msgpack::object_kv) * num_kv_pairs, MSGPACK_ZONE_ALIGNOF(msgpack::object_kv)); |
781 | 0 | m_ptr->via.map.size = num_kv_pairs; |
782 | 0 | m_objs.push_back(elem(m_ptr->via.map.ptr)); |
783 | 0 | return true; |
784 | 0 | } |
785 | 0 | bool start_map_key() { |
786 | 0 | m_ptr = m_objs.back().get_key(); |
787 | 0 | return true; |
788 | 0 | } |
789 | 0 | bool end_map_key() { |
790 | 0 | return true; |
791 | 0 | } |
792 | 0 | bool start_map_value() { |
793 | 0 | m_ptr = m_objs.back().get_val(); |
794 | 0 | return true; |
795 | 0 | } |
796 | 0 | bool end_map_value() { |
797 | 0 | ++m_objs.back().as.kv; |
798 | 0 | return true; |
799 | 0 | } |
800 | 0 | bool end_map() { |
801 | 0 | m_objs.pop_back(); |
802 | 0 | return true; |
803 | 0 | } |
804 | | private: |
805 | | struct elem { |
806 | | elem(msgpack::object* obj) |
807 | 0 | :is_obj(true) { |
808 | 0 | as.obj = obj; |
809 | 0 | } |
810 | | elem(msgpack::object_kv* kv) |
811 | 0 | :is_obj(false) { |
812 | 0 | as.kv = kv; |
813 | 0 | } |
814 | 0 | msgpack::object* get_item() { |
815 | 0 | return as.obj; |
816 | 0 | } |
817 | 0 | msgpack::object* get_key() { |
818 | 0 | return &as.kv->key; |
819 | 0 | } |
820 | 0 | msgpack::object* get_val() { |
821 | 0 | return &as.kv->val; |
822 | 0 | } |
823 | | union { |
824 | | msgpack::object* obj; |
825 | | msgpack::object_kv* kv; |
826 | | } as; |
827 | | bool is_obj; |
828 | | }; |
829 | | std::vector<elem> m_objs; |
830 | | msgpack::zone& m_zone; |
831 | | msgpack::object* m_ptr; |
832 | | }; |
833 | | }; |
834 | | |
835 | | // Adaptor functor specialization to object::with_zone |
836 | | |
837 | | template <> |
838 | | struct object_with_zone<msgpack::object::with_zone> { |
839 | | void operator()( |
840 | | msgpack::object::with_zone& o, |
841 | 0 | msgpack::object::with_zone const& v) const { |
842 | 0 | o << static_cast<msgpack::object const&>(v); |
843 | 0 | } |
844 | | }; |
845 | | |
846 | | |
847 | | } // namespace adaptor |
848 | | |
849 | | |
850 | | // obsolete |
851 | | template <typename Type> |
852 | | class define : public Type { |
853 | | public: |
854 | | typedef Type msgpack_type; |
855 | | typedef define<Type> define_type; |
856 | | define() {} |
857 | | define(const msgpack_type& v) : msgpack_type(v) {} |
858 | | |
859 | | template <typename Packer> |
860 | | void msgpack_pack(Packer& o) const |
861 | | { |
862 | | msgpack::operator<<(o, static_cast<const msgpack_type&>(*this)); |
863 | | } |
864 | | |
865 | | void msgpack_unpack(object const& o) |
866 | | { |
867 | | msgpack::operator>>(o, static_cast<msgpack_type&>(*this)); |
868 | | } |
869 | | }; |
870 | | |
871 | | // deconvert operator |
872 | | |
873 | | template <typename Stream> |
874 | | template <typename T> |
875 | | inline msgpack::packer<Stream>& packer<Stream>::pack(const T& v) |
876 | 1.19k | { |
877 | 1.19k | msgpack::operator<<(*this, v); |
878 | 1.19k | return *this; |
879 | 1.19k | } |
880 | | |
881 | | struct object_equal_visitor { |
882 | | object_equal_visitor(msgpack::object const& obj, bool& result) |
883 | 0 | :m_ptr(&obj), m_result(result) {} |
884 | 0 | bool visit_nil() { |
885 | 0 | if (m_ptr->type != msgpack::type::NIL) { |
886 | 0 | m_result = false; |
887 | 0 | return false; |
888 | 0 | } |
889 | 0 | return true; |
890 | 0 | } |
891 | 0 | bool visit_boolean(bool v) { |
892 | 0 | if (m_ptr->type != msgpack::type::BOOLEAN || m_ptr->via.boolean != v) { |
893 | 0 | m_result = false; |
894 | 0 | return false; |
895 | 0 | } |
896 | 0 | return true; |
897 | 0 | } |
898 | 0 | bool visit_positive_integer(uint64_t v) { |
899 | 0 | if (m_ptr->type != msgpack::type::POSITIVE_INTEGER || m_ptr->via.u64 != v) { |
900 | 0 | m_result = false; |
901 | 0 | return false; |
902 | 0 | } |
903 | 0 | return true; |
904 | 0 | } |
905 | 0 | bool visit_negative_integer(int64_t v) { |
906 | 0 | if (m_ptr->type != msgpack::type::NEGATIVE_INTEGER || m_ptr->via.i64 != v) { |
907 | 0 | m_result = false; |
908 | 0 | return false; |
909 | 0 | } |
910 | 0 | return true; |
911 | 0 | } |
912 | 0 | bool visit_float32(float v) { |
913 | 0 | if (m_ptr->type != msgpack::type::FLOAT32 || m_ptr->via.f64 != v) { |
914 | 0 | m_result = false; |
915 | 0 | return false; |
916 | 0 | } |
917 | 0 | return true; |
918 | 0 | } |
919 | 0 | bool visit_float64(double v) { |
920 | 0 | if (m_ptr->type != msgpack::type::FLOAT64 || m_ptr->via.f64 != v) { |
921 | 0 | m_result = false; |
922 | 0 | return false; |
923 | 0 | } |
924 | 0 | return true; |
925 | 0 | } |
926 | 0 | bool visit_str(const char* v, uint32_t size) { |
927 | 0 | if (m_ptr->type != msgpack::type::STR || |
928 | 0 | m_ptr->via.str.size != size || |
929 | 0 | std::memcmp(m_ptr->via.str.ptr, v, size) != 0) { |
930 | 0 | m_result = false; |
931 | 0 | return false; |
932 | 0 | } |
933 | 0 | return true; |
934 | 0 | } |
935 | 0 | bool visit_bin(const char* v, uint32_t size) { |
936 | 0 | if (m_ptr->type != msgpack::type::BIN || |
937 | 0 | m_ptr->via.bin.size != size || |
938 | 0 | std::memcmp(m_ptr->via.bin.ptr, v, size) != 0) { |
939 | 0 | m_result = false; |
940 | 0 | return false; |
941 | 0 | } |
942 | 0 | return true; |
943 | 0 | } |
944 | 0 | bool visit_ext(const char* v, uint32_t size) { |
945 | 0 | if (m_ptr->type != msgpack::type::EXT || |
946 | 0 | m_ptr->via.ext.size != size - 1 || |
947 | 0 | std::memcmp(m_ptr->via.ext.ptr, v, size) != 0) { |
948 | 0 | m_result = false; |
949 | 0 | return false; |
950 | 0 | } |
951 | 0 | return true; |
952 | 0 | } |
953 | 0 | bool start_array(uint32_t num_elements) { |
954 | 0 | if (m_ptr->type != msgpack::type::ARRAY || |
955 | 0 | m_ptr->via.array.size != num_elements) { |
956 | 0 | m_result = false; |
957 | 0 | return false; |
958 | 0 | } |
959 | 0 | m_objs.push_back(elem(m_ptr->via.array.ptr)); |
960 | 0 | return true; |
961 | 0 | } |
962 | 0 | bool start_array_item() { |
963 | 0 | m_ptr = m_objs.back().get_item(); |
964 | 0 | return true; |
965 | 0 | } |
966 | 0 | bool end_array_item() { |
967 | 0 | ++m_objs.back().as.obj; |
968 | 0 | return true; |
969 | 0 | } |
970 | 0 | bool end_array() { |
971 | 0 | m_objs.pop_back(); |
972 | 0 | return true; |
973 | 0 | } |
974 | 0 | bool start_map(uint32_t num_kv_pairs) { |
975 | 0 | if (m_ptr->type != msgpack::type::MAP || |
976 | 0 | m_ptr->via.array.size != num_kv_pairs) { |
977 | 0 | m_result = false; |
978 | 0 | return false; |
979 | 0 | } |
980 | 0 | m_objs.push_back(elem(m_ptr->via.map.ptr)); |
981 | 0 | return true; |
982 | 0 | } |
983 | 0 | bool start_map_key() { |
984 | 0 | m_ptr = m_objs.back().get_key(); |
985 | 0 | return true; |
986 | 0 | } |
987 | 0 | bool end_map_key() { |
988 | 0 | return true; |
989 | 0 | } |
990 | 0 | bool start_map_value() { |
991 | 0 | m_ptr = m_objs.back().get_val(); |
992 | 0 | return true; |
993 | 0 | } |
994 | 0 | bool end_map_value() { |
995 | 0 | ++m_objs.back().as.kv; |
996 | 0 | return true; |
997 | 0 | } |
998 | 0 | bool end_map() { |
999 | 0 | m_objs.pop_back(); |
1000 | 0 | return true; |
1001 | 0 | } |
1002 | | private: |
1003 | | struct elem { |
1004 | | elem(msgpack::object const* obj) |
1005 | 0 | :is_obj(true) { |
1006 | 0 | as.obj = obj; |
1007 | 0 | } |
1008 | | elem(msgpack::object_kv const* kv) |
1009 | 0 | :is_obj(false) { |
1010 | 0 | as.kv = kv; |
1011 | 0 | } |
1012 | 0 | msgpack::object const* get_item() { |
1013 | 0 | return as.obj; |
1014 | 0 | } |
1015 | 0 | msgpack::object const* get_key() { |
1016 | 0 | return &as.kv->key; |
1017 | 0 | } |
1018 | 0 | msgpack::object const* get_val() { |
1019 | 0 | return &as.kv->val; |
1020 | 0 | } |
1021 | | union { |
1022 | | msgpack::object const* obj; |
1023 | | msgpack::object_kv const* kv; |
1024 | | } as; |
1025 | | bool is_obj; |
1026 | | }; |
1027 | | std::vector<elem> m_objs; |
1028 | | msgpack::object const* m_ptr; |
1029 | | bool& m_result; |
1030 | | }; |
1031 | | |
1032 | | inline bool operator==(const msgpack::object& x, const msgpack::object& y) |
1033 | 0 | { |
1034 | 0 | if(x.type != y.type) { return false; } |
1035 | 0 | bool b = true; |
1036 | 0 | object_equal_visitor vis(y, b); |
1037 | 0 | msgpack::object_parser(x).parse(vis); |
1038 | 0 | return b; |
1039 | 0 | } |
1040 | | |
1041 | | template <typename T> |
1042 | | inline bool operator==(const msgpack::object& x, const T& y) |
1043 | | try { |
1044 | | return x == msgpack::object(y); |
1045 | | } catch (msgpack::type_error&) { |
1046 | | return false; |
1047 | | } |
1048 | | |
1049 | | inline bool operator!=(const msgpack::object& x, const msgpack::object& y) |
1050 | 0 | { return !(x == y); } |
1051 | | |
1052 | | template <typename T> |
1053 | | inline bool operator==(const T& y, const msgpack::object& x) |
1054 | | { return x == y; } |
1055 | | |
1056 | | template <typename T> |
1057 | | inline bool operator!=(const msgpack::object& x, const T& y) |
1058 | | { return !(x == y); } |
1059 | | |
1060 | | template <typename T> |
1061 | | inline bool operator!=(const T& y, const msgpack::object& x) |
1062 | | { return x != y; } |
1063 | | |
1064 | | |
1065 | | inline object::implicit_type object::convert() const |
1066 | 0 | { |
1067 | 0 | return object::implicit_type(*this); |
1068 | 0 | } |
1069 | | |
1070 | | template <typename T> |
1071 | | inline |
1072 | | typename msgpack::enable_if< |
1073 | | !msgpack::is_array<T>::value && !msgpack::is_pointer<T>::value, |
1074 | | T& |
1075 | | >::type |
1076 | | object::convert(T& v) const |
1077 | 0 | { |
1078 | 0 | msgpack::operator>>(*this, v); |
1079 | 0 | return v; |
1080 | 0 | } |
1081 | | |
1082 | | template <typename T, std::size_t N> |
1083 | | inline T(&object::convert(T(&v)[N]) const)[N] |
1084 | | { |
1085 | | msgpack::operator>>(*this, v); |
1086 | | return v; |
1087 | | } |
1088 | | |
1089 | | #if !defined(MSGPACK_DISABLE_LEGACY_CONVERT) |
1090 | | template <typename T> |
1091 | | inline |
1092 | | typename msgpack::enable_if< |
1093 | | msgpack::is_pointer<T>::value, |
1094 | | T |
1095 | | >::type |
1096 | | object::convert(T v) const |
1097 | | { |
1098 | | convert(*v); |
1099 | | return v; |
1100 | | } |
1101 | | #endif // !defined(MSGPACK_DISABLE_LEGACY_CONVERT) |
1102 | | |
1103 | | template <typename T> |
1104 | | inline bool object::convert_if_not_nil(T& v) const |
1105 | | { |
1106 | | if (is_nil()) { |
1107 | | return false; |
1108 | | } |
1109 | | convert(v); |
1110 | | return true; |
1111 | | } |
1112 | | |
1113 | | #if defined(MSGPACK_USE_CPP03) |
1114 | | |
1115 | | template <typename T> |
1116 | | inline T object::as() const |
1117 | | { |
1118 | | T v; |
1119 | | convert(v); |
1120 | | return v; |
1121 | | } |
1122 | | |
1123 | | #else // defined(MSGPACK_USE_CPP03) |
1124 | | |
1125 | | template <typename T> |
1126 | | inline typename std::enable_if<msgpack::has_as<T>::value, T>::type object::as() const { |
1127 | | return msgpack::adaptor::as<T>()(*this); |
1128 | | } |
1129 | | |
1130 | | template <typename T> |
1131 | 0 | inline typename std::enable_if<!msgpack::has_as<T>::value, T>::type object::as() const { |
1132 | 0 | T v; |
1133 | 0 | convert(v); |
1134 | 0 | return v; |
1135 | 0 | } |
1136 | | |
1137 | | #endif // defined(MSGPACK_USE_CPP03) |
1138 | | |
1139 | | inline object::object() |
1140 | 4.50k | { |
1141 | 4.50k | type = msgpack::type::NIL; |
1142 | 4.50k | } |
1143 | | |
1144 | | template <typename T> |
1145 | | inline object::object(const T& v) |
1146 | | { |
1147 | | *this << v; |
1148 | | } |
1149 | | |
1150 | | template <typename T> |
1151 | | inline object& object::operator=(const T& v) |
1152 | | { |
1153 | | *this = object(v); |
1154 | | return *this; |
1155 | | } |
1156 | | |
1157 | | template <typename T> |
1158 | | inline object::object(const T& v, msgpack::zone& z) |
1159 | | { |
1160 | | with_zone oz(z); |
1161 | | msgpack::operator<<(oz, v); |
1162 | | type = oz.type; |
1163 | | via = oz.via; |
1164 | | } |
1165 | | |
1166 | | template <typename T> |
1167 | | inline object::object(const T& v, msgpack::zone* z) |
1168 | | { |
1169 | | with_zone oz(*z); |
1170 | | msgpack::operator<<(oz, v); |
1171 | | type = oz.type; |
1172 | | via = oz.via; |
1173 | | } |
1174 | | |
1175 | | |
1176 | | // obsolete |
1177 | | template <typename T> |
1178 | | inline void convert(T& v, msgpack::object const& o) |
1179 | | { |
1180 | | o.convert(v); |
1181 | | } |
1182 | | |
1183 | | // obsolete |
1184 | | template <typename Stream, typename T> |
1185 | | inline void pack(msgpack::packer<Stream>& o, const T& v) |
1186 | | { |
1187 | | o.pack(v); |
1188 | | } |
1189 | | |
1190 | | // obsolete |
1191 | | template <typename Stream, typename T> |
1192 | | inline void pack_copy(msgpack::packer<Stream>& o, T v) |
1193 | | { |
1194 | | pack(o, v); |
1195 | | } |
1196 | | |
1197 | | template <typename Stream> |
1198 | | inline msgpack::packer<Stream>& operator<< (msgpack::packer<Stream>& o, const msgpack::object& v) |
1199 | | { |
1200 | | object_pack_visitor<Stream> vis(o); |
1201 | | msgpack::object_parser(v).parse(vis); |
1202 | | return o; |
1203 | | } |
1204 | | |
1205 | | template <typename Stream> |
1206 | | inline msgpack::packer<Stream>& operator<< (msgpack::packer<Stream>& o, const msgpack::object::with_zone& v) |
1207 | | { |
1208 | | return o << static_cast<msgpack::object>(v); |
1209 | | } |
1210 | | |
1211 | | inline std::ostream& operator<< (std::ostream& s, const msgpack::object& v) |
1212 | 0 | { |
1213 | 0 | object_stringize_visitor vis(s); |
1214 | 0 | msgpack::object_parser(v).parse(vis); |
1215 | 0 | return s; |
1216 | 0 | } |
1217 | | |
1218 | | /// @cond |
1219 | | } // MSGPACK_API_VERSION_NAMESPACE(v1) |
1220 | | /// @endcond |
1221 | | |
1222 | | } // namespace msgpack |
1223 | | |
1224 | | #endif // MSGPACK_V1_OBJECT_HPP |