/src/jsoncons/include/jsoncons_ext/msgpack/msgpack_parser.hpp
Line  | Count  | Source  | 
1  |  | // Copyright 2013-2025 Daniel Parker  | 
2  |  | // Distributed under the Boost license, Version 1.0.  | 
3  |  | // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)  | 
4  |  |  | 
5  |  | // See https://github.com/danielaparker/jsoncons for latest version  | 
6  |  |  | 
7  |  | #ifndef JSONCONS_EXT_MSGPACK_MSGPACK_PARSER_HPP  | 
8  |  | #define JSONCONS_EXT_MSGPACK_MSGPACK_PARSER_HPP  | 
9  |  |  | 
10  |  | #include <cstddef>  | 
11  |  | #include <cstdint>  | 
12  |  | #include <memory>  | 
13  |  | #include <string>  | 
14  |  | #include <system_error>  | 
15  |  | #include <utility> // std::move  | 
16  |  | #include <vector>  | 
17  |  |  | 
18  |  | #include <jsoncons/config/compiler_support.hpp>  | 
19  |  | #include <jsoncons/config/jsoncons_config.hpp>  | 
20  |  | #include <jsoncons/item_event_visitor.hpp>  | 
21  |  | #include <jsoncons/json_type.hpp>  | 
22  |  | #include <jsoncons/semantic_tag.hpp>  | 
23  |  | #include <jsoncons/ser_util.hpp>  | 
24  |  | #include <jsoncons/source.hpp>  | 
25  |  | #include <jsoncons/utility/bigint.hpp>  | 
26  |  | #include <jsoncons/utility/binary.hpp>  | 
27  |  | #include <jsoncons/utility/byte_string.hpp>  | 
28  |  | #include <jsoncons/utility/unicode_traits.hpp>  | 
29  |  |  | 
30  |  | #include <jsoncons_ext/msgpack/msgpack_error.hpp>  | 
31  |  | #include <jsoncons_ext/msgpack/msgpack_options.hpp>  | 
32  |  | #include <jsoncons_ext/msgpack/msgpack_type.hpp>  | 
33  |  |  | 
34  |  | namespace jsoncons {  | 
35  |  | namespace msgpack { | 
36  |  |  | 
37  |  | enum class parse_mode {root,accept,array,map_key,map_value}; | 
38  |  |  | 
39  |  | struct parse_state   | 
40  |  | { | 
41  |  |     parse_mode mode;   | 
42  |  |     std::size_t length{0}; | 
43  |  |     std::size_t index{0}; | 
44  |  |  | 
45  |  |     parse_state(parse_mode mode, std::size_t length) noexcept  | 
46  | 15.1M  |         : mode(mode), length(length)  | 
47  | 15.1M  |     { | 
48  | 15.1M  |     }  | 
49  |  |  | 
50  |  |     parse_state(const parse_state&) = default;  | 
51  |  |     parse_state(parse_state&&) = default;  | 
52  |  |       | 
53  |  |     ~parse_state() = default;  | 
54  |  | };  | 
55  |  |  | 
56  |  | template <typename Source,typename Allocator=std::allocator<char>>  | 
57  |  | class basic_msgpack_parser : public ser_context  | 
58  |  | { | 
59  |  |     using char_type = char;  | 
60  |  |     using char_traits_type = std::char_traits<char>;  | 
61  |  |     using temp_allocator_type = Allocator;  | 
62  |  |     using char_allocator_type = typename std::allocator_traits<temp_allocator_type>:: template rebind_alloc<char_type>;                    | 
63  |  |     using byte_allocator_type = typename std::allocator_traits<temp_allocator_type>:: template rebind_alloc<uint8_t>;                    | 
64  |  |     using int64_allocator_type = typename std::allocator_traits<temp_allocator_type>:: template rebind_alloc<int64_t>;                    | 
65  |  |     using parse_state_allocator_type = typename std::allocator_traits<temp_allocator_type>:: template rebind_alloc<parse_state>;                           | 
66  |  |  | 
67  |  |     static constexpr int64_t nanos_in_second = 1000000000;  | 
68  |  |  | 
69  |  |     bool more_{true}; | 
70  |  |     bool done_{false}; | 
71  |  |     int nesting_depth_{0}; | 
72  |  |     bool cursor_mode_{false}; | 
73  |  |     int mark_level_{0}; | 
74  |  |  | 
75  |  |     Source source_;  | 
76  |  |     msgpack_decode_options options_;  | 
77  |  |     std::basic_string<char,std::char_traits<char>,char_allocator_type> text_buffer_;  | 
78  |  |     std::vector<uint8_t,byte_allocator_type> bytes_buffer_;  | 
79  |  |     std::vector<parse_state,parse_state_allocator_type> state_stack_;  | 
80  |  |  | 
81  |  | public:  | 
82  |  |     template <typename Sourceable>  | 
83  |  |     basic_msgpack_parser(Sourceable&& source,  | 
84  |  |                          const msgpack_decode_options& options = msgpack_decode_options(),  | 
85  |  |                          const Allocator& alloc = Allocator())  | 
86  | 17.6k  |        : source_(std::forward<Sourceable>(source)),  | 
87  | 17.6k  |          options_(options),  | 
88  | 17.6k  |          text_buffer_(alloc),  | 
89  | 17.6k  |          bytes_buffer_(alloc),  | 
90  | 17.6k  |          state_stack_(alloc)  | 
91  | 17.6k  |     { | 
92  | 17.6k  |         state_stack_.emplace_back(parse_mode::root,0);  | 
93  | 17.6k  |     } jsoncons::msgpack::basic_msgpack_parser<jsoncons::stream_source<unsigned char, std::__1::allocator<unsigned char> >, std::__1::allocator<char> >::basic_msgpack_parser<std::__1::basic_istringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >&>(std::__1::basic_istringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, jsoncons::msgpack::msgpack_decode_options const&, std::__1::allocator<char> const&) Line  | Count  | Source  |  86  | 10.7k  |        : source_(std::forward<Sourceable>(source)),  |  87  | 10.7k  |          options_(options),  |  88  | 10.7k  |          text_buffer_(alloc),  |  89  | 10.7k  |          bytes_buffer_(alloc),  |  90  | 10.7k  |          state_stack_(alloc)  |  91  | 10.7k  |     { |  92  | 10.7k  |         state_stack_.emplace_back(parse_mode::root,0);  |  93  | 10.7k  |     }  |  
 jsoncons::msgpack::basic_msgpack_parser<jsoncons::stream_source<unsigned char, std::__1::allocator<unsigned char> >, std::__1::allocator<char> >::basic_msgpack_parser<std::__1::basic_istream<char, std::__1::char_traits<char> >&>(std::__1::basic_istream<char, std::__1::char_traits<char> >&, jsoncons::msgpack::msgpack_decode_options const&, std::__1::allocator<char> const&) Line  | Count  | Source  |  86  | 6.82k  |        : source_(std::forward<Sourceable>(source)),  |  87  | 6.82k  |          options_(options),  |  88  | 6.82k  |          text_buffer_(alloc),  |  89  | 6.82k  |          bytes_buffer_(alloc),  |  90  | 6.82k  |          state_stack_(alloc)  |  91  | 6.82k  |     { |  92  | 6.82k  |         state_stack_.emplace_back(parse_mode::root,0);  |  93  | 6.82k  |     }  |  
  | 
94  |  |  | 
95  |  |     void restart()  | 
96  |  |     { | 
97  |  |         more_ = true;  | 
98  |  |     }  | 
99  |  |  | 
100  |  |     void reset()  | 
101  | 17.6k  |     { | 
102  | 17.6k  |         more_ = true;  | 
103  | 17.6k  |         done_ = false;  | 
104  | 17.6k  |         text_buffer_.clear();  | 
105  | 17.6k  |         bytes_buffer_.clear();  | 
106  | 17.6k  |         state_stack_.clear();  | 
107  | 17.6k  |         state_stack_.emplace_back(parse_mode::root,0);  | 
108  | 17.6k  |         nesting_depth_ = 0;  | 
109  | 17.6k  |     }  | 
110  |  |  | 
111  |  |     template <typename Sourceable>  | 
112  |  |     void reset(Sourceable&& source)  | 
113  |  |     { | 
114  |  |         source_ = std::forward<Sourceable>(source);  | 
115  |  |         reset();  | 
116  |  |     }  | 
117  |  |  | 
118  |  |     void cursor_mode(bool value)  | 
119  |  |     { | 
120  |  |         cursor_mode_ = value;  | 
121  |  |     }  | 
122  |  |  | 
123  |  |     int level() const  | 
124  |  |     { | 
125  |  |         return static_cast<int>(state_stack_.size());  | 
126  |  |     }  | 
127  |  |  | 
128  |  |     int mark_level() const   | 
129  |  |     { | 
130  |  |         return mark_level_;  | 
131  |  |     }  | 
132  |  |  | 
133  |  |     void mark_level(int value)  | 
134  |  |     { | 
135  |  |         mark_level_ = value;  | 
136  |  |     }  | 
137  |  |  | 
138  |  |     bool done() const  | 
139  |  |     { | 
140  |  |         return done_;  | 
141  |  |     }  | 
142  |  |  | 
143  |  |     bool stopped() const  | 
144  |  |     { | 
145  |  |         return !more_;  | 
146  |  |     }  | 
147  |  |  | 
148  |  |     std::size_t line() const override  | 
149  | 4.37k  |     { | 
150  | 4.37k  |         return 0;  | 
151  | 4.37k  |     }  | 
152  |  |  | 
153  |  |     std::size_t column() const override  | 
154  | 4.37k  |     { | 
155  | 4.37k  |         return source_.position();  | 
156  | 4.37k  |     }  | 
157  |  |  | 
158  |  |     void parse(item_event_visitor& visitor, std::error_code& ec)  | 
159  | 17.6k  |     { | 
160  | 154M  |         while (!done_ && more_)  | 
161  | 154M  |         { | 
162  | 154M  |             switch (state_stack_.back().mode)  | 
163  | 154M  |             { | 
164  | 101M  |                 case parse_mode::array:  | 
165  | 101M  |                 { | 
166  | 101M  |                     if (state_stack_.back().index < state_stack_.back().length)  | 
167  | 92.7M  |                     { | 
168  | 92.7M  |                         ++state_stack_.back().index;  | 
169  | 92.7M  |                         read_item(visitor, ec);  | 
170  | 92.7M  |                         if (JSONCONS_UNLIKELY(ec))  | 
171  | 3.59k  |                         { | 
172  | 3.59k  |                             return;  | 
173  | 3.59k  |                         }  | 
174  | 92.7M  |                     }  | 
175  | 9.09M  |                     else  | 
176  | 9.09M  |                     { | 
177  | 9.09M  |                         end_array(visitor, ec);  | 
178  | 9.09M  |                     }  | 
179  | 101M  |                     break;  | 
180  | 101M  |                 }  | 
181  | 101M  |                 case parse_mode::map_key:  | 
182  | 29.2M  |                 { | 
183  | 29.2M  |                     if (state_stack_.back().index < state_stack_.back().length)  | 
184  | 23.4M  |                     { | 
185  | 23.4M  |                         ++state_stack_.back().index;  | 
186  | 23.4M  |                         state_stack_.back().mode = parse_mode::map_value;  | 
187  | 23.4M  |                         read_item(visitor, ec);  | 
188  | 23.4M  |                         if (JSONCONS_UNLIKELY(ec))  | 
189  | 2.25k  |                         { | 
190  | 2.25k  |                             return;  | 
191  | 2.25k  |                         }  | 
192  | 23.4M  |                     }  | 
193  | 5.87M  |                     else  | 
194  | 5.87M  |                     { | 
195  | 5.87M  |                         end_object(visitor, ec);  | 
196  | 5.87M  |                     }  | 
197  | 29.2M  |                     break;  | 
198  | 29.2M  |                 }  | 
199  | 29.2M  |                 case parse_mode::map_value:  | 
200  | 23.3M  |                 { | 
201  | 23.3M  |                     state_stack_.back().mode = parse_mode::map_key;  | 
202  | 23.3M  |                     read_item(visitor, ec);  | 
203  | 23.3M  |                     if (JSONCONS_UNLIKELY(ec))  | 
204  | 5.81k  |                     { | 
205  | 5.81k  |                         return;  | 
206  | 5.81k  |                     }  | 
207  | 23.3M  |                     break;  | 
208  | 23.3M  |                 }  | 
209  | 23.3M  |                 case parse_mode::root:  | 
210  | 17.6k  |                 { | 
211  | 17.6k  |                     state_stack_.back().mode = parse_mode::accept;  | 
212  | 17.6k  |                     read_item(visitor, ec);  | 
213  | 17.6k  |                     if (JSONCONS_UNLIKELY(ec))  | 
214  | 1.13k  |                     { | 
215  | 1.13k  |                         return;  | 
216  | 1.13k  |                     }  | 
217  | 16.4k  |                     break;  | 
218  | 17.6k  |                 }  | 
219  | 16.4k  |                 case parse_mode::accept:  | 
220  | 4.81k  |                 { | 
221  | 4.81k  |                     JSONCONS_ASSERT(state_stack_.size() == 1);  | 
222  | 4.81k  |                     state_stack_.clear();  | 
223  | 4.81k  |                     more_ = false;  | 
224  | 4.81k  |                     done_ = true;  | 
225  | 4.81k  |                     visitor.flush();  | 
226  | 4.81k  |                     break;  | 
227  | 4.81k  |                 }  | 
228  | 154M  |             }  | 
229  | 154M  |         }  | 
230  | 17.6k  |     }  | 
231  |  | private:  | 
232  |  |  | 
233  |  |     void read_item(item_event_visitor& visitor, std::error_code& ec)  | 
234  | 139M  |     { | 
235  | 139M  |         if (source_.is_error())  | 
236  | 0  |         { | 
237  | 0  |             ec = msgpack_errc::source_error;  | 
238  | 0  |             more_ = false;  | 
239  | 0  |             return;  | 
240  | 0  |         }     | 
241  |  |  | 
242  | 139M  |         uint8_t type;  | 
243  | 139M  |         if (source_.read(&type, 1) == 0)  | 
244  | 10.3k  |         { | 
245  | 10.3k  |             ec = msgpack_errc::unexpected_eof;  | 
246  | 10.3k  |             more_ = false;  | 
247  | 10.3k  |             return;  | 
248  | 10.3k  |         }  | 
249  |  |  | 
250  | 139M  |         if (type <= 0xbf)  | 
251  | 66.2M  |         { | 
252  | 66.2M  |             if (type <= 0x7f)   | 
253  | 46.0M  |             { | 
254  |  |                 // positive fixint  | 
255  | 46.0M  |                 visitor.uint64_value(type, semantic_tag::none, *this, ec);  | 
256  | 46.0M  |                 more_ = !cursor_mode_;  | 
257  | 46.0M  |             }  | 
258  | 20.1M  |             else if (type <= 0x8f)   | 
259  | 5.91M  |             { | 
260  | 5.91M  |                 begin_object(visitor,type,ec); // fixmap  | 
261  | 5.91M  |             }  | 
262  | 14.2M  |             else if (type <= 0x9f)   | 
263  | 9.17M  |             { | 
264  | 9.17M  |                 begin_array(visitor,type,ec); // fixarray  | 
265  | 9.17M  |             }  | 
266  | 5.08M  |             else   | 
267  | 5.08M  |             { | 
268  |  |                 // fixstr  | 
269  | 5.08M  |                 const size_t len = type & 0x1f;  | 
270  |  |  | 
271  | 5.08M  |                 text_buffer_.clear();  | 
272  |  |  | 
273  | 5.08M  |                 if (source_reader<Source>::read(source_,text_buffer_,len) != static_cast<std::size_t>(len))  | 
274  | 83  |                 { | 
275  | 83  |                     ec = msgpack_errc::unexpected_eof;  | 
276  | 83  |                     more_ = false;  | 
277  | 83  |                     return;  | 
278  | 83  |                 }  | 
279  |  |  | 
280  | 5.08M  |                 auto result = unicode_traits::validate(text_buffer_.data(),text_buffer_.size());  | 
281  | 5.08M  |                 if (result.ec != unicode_traits::conv_errc())  | 
282  | 288  |                 { | 
283  | 288  |                     ec = msgpack_errc::invalid_utf8_text_string;  | 
284  | 288  |                     more_ = false;  | 
285  | 288  |                     return;  | 
286  | 288  |                 }  | 
287  | 5.08M  |                 visitor.string_value(jsoncons::basic_string_view<char>(text_buffer_.data(),text_buffer_.length()), semantic_tag::none, *this, ec);  | 
288  | 5.08M  |                 more_ = !cursor_mode_;  | 
289  | 5.08M  |             }  | 
290  | 66.2M  |         }  | 
291  | 73.2M  |         else if (type >= 0xe0)   | 
292  | 8.61M  |         { | 
293  |  |             // negative fixint  | 
294  | 8.61M  |             visitor.int64_value(static_cast<int8_t>(type), semantic_tag::none, *this, ec);  | 
295  | 8.61M  |             more_ = !cursor_mode_;  | 
296  | 8.61M  |         }  | 
297  | 64.6M  |         else  | 
298  | 64.6M  |         { | 
299  | 64.6M  |             switch (type)  | 
300  | 64.6M  |             { | 
301  | 2.92M  |                 case jsoncons::msgpack::msgpack_type::nil_type:   | 
302  | 2.92M  |                 { | 
303  | 2.92M  |                     visitor.null_value(semantic_tag::none, *this, ec);  | 
304  | 2.92M  |                     more_ = !cursor_mode_;  | 
305  | 2.92M  |                     break;  | 
306  | 0  |                 }  | 
307  | 9.12M  |                 case jsoncons::msgpack::msgpack_type::true_type:  | 
308  | 9.12M  |                 { | 
309  | 9.12M  |                     visitor.bool_value(true, semantic_tag::none, *this, ec);  | 
310  | 9.12M  |                     more_ = !cursor_mode_;  | 
311  | 9.12M  |                     break;  | 
312  | 0  |                 }  | 
313  | 51.6M  |                 case jsoncons::msgpack::msgpack_type::false_type:  | 
314  | 51.6M  |                 { | 
315  | 51.6M  |                     visitor.bool_value(false, semantic_tag::none, *this, ec);  | 
316  | 51.6M  |                     more_ = !cursor_mode_;  | 
317  | 51.6M  |                     break;  | 
318  | 0  |                 }  | 
319  | 208k  |                 case jsoncons::msgpack::msgpack_type::float32_type:   | 
320  | 208k  |                 { | 
321  | 208k  |                     uint8_t buf[sizeof(float)];  | 
322  | 208k  |                     if (source_.read(buf, sizeof(float)) != sizeof(float))  | 
323  | 50  |                     { | 
324  | 50  |                         ec = msgpack_errc::unexpected_eof;  | 
325  | 50  |                         more_ = false;  | 
326  | 50  |                         return;  | 
327  | 50  |                     }  | 
328  | 208k  |                     float val = binary::big_to_native<float>(buf, sizeof(buf));  | 
329  | 208k  |                     visitor.double_value(val, semantic_tag::none, *this, ec);  | 
330  | 208k  |                     more_ = !cursor_mode_;  | 
331  | 208k  |                     break;  | 
332  | 208k  |                 }  | 
333  |  |  | 
334  | 27.9k  |                 case jsoncons::msgpack::msgpack_type::float64_type:   | 
335  | 27.9k  |                 { | 
336  | 27.9k  |                     uint8_t buf[sizeof(double)];  | 
337  | 27.9k  |                     if (source_.read(buf, sizeof(double)) != sizeof(double))  | 
338  | 32  |                     { | 
339  | 32  |                         ec = msgpack_errc::unexpected_eof;  | 
340  | 32  |                         more_ = false;  | 
341  | 32  |                         return;  | 
342  | 32  |                     }  | 
343  | 27.8k  |                     double val = binary::big_to_native<double>(buf, sizeof(buf));  | 
344  | 27.8k  |                     visitor.double_value(val, semantic_tag::none, *this, ec);  | 
345  | 27.8k  |                     more_ = !cursor_mode_;  | 
346  | 27.8k  |                     break;  | 
347  | 27.9k  |                 }  | 
348  |  |  | 
349  | 40.8k  |                 case jsoncons::msgpack::msgpack_type::uint8_type:   | 
350  | 40.8k  |                 { | 
351  | 40.8k  |                     uint8_t b;  | 
352  | 40.8k  |                     if (source_.read(&b, 1) == 0)  | 
353  | 6  |                     { | 
354  | 6  |                         ec = msgpack_errc::unexpected_eof;  | 
355  | 6  |                         more_ = false;  | 
356  | 6  |                         return;  | 
357  | 6  |                     }  | 
358  | 40.8k  |                     visitor.uint64_value(b, semantic_tag::none, *this, ec);  | 
359  | 40.8k  |                     more_ = !cursor_mode_;  | 
360  | 40.8k  |                     break;  | 
361  | 40.8k  |                 }  | 
362  |  |  | 
363  | 3.56k  |                 case jsoncons::msgpack::msgpack_type::uint16_type:   | 
364  | 3.56k  |                 { | 
365  | 3.56k  |                     uint8_t buf[sizeof(uint16_t)];  | 
366  | 3.56k  |                     if (source_.read(buf, sizeof(uint16_t)) !=sizeof(uint16_t))   | 
367  | 6  |                     { | 
368  | 6  |                         ec = msgpack_errc::unexpected_eof;  | 
369  | 6  |                         more_ = false;  | 
370  | 6  |                         return;  | 
371  | 6  |                     }  | 
372  | 3.55k  |                     uint16_t val = binary::big_to_native<uint16_t>(buf, sizeof(buf));  | 
373  | 3.55k  |                     visitor.uint64_value(val, semantic_tag::none, *this, ec);  | 
374  | 3.55k  |                     more_ = !cursor_mode_;  | 
375  | 3.55k  |                     break;  | 
376  | 3.56k  |                 }  | 
377  |  |  | 
378  | 20.9k  |                 case jsoncons::msgpack::msgpack_type::uint32_type:   | 
379  | 20.9k  |                 { | 
380  | 20.9k  |                     uint8_t buf[sizeof(uint32_t)];  | 
381  | 20.9k  |                     if (source_.read(buf, sizeof(uint32_t)) != sizeof(uint32_t))  | 
382  | 12  |                     { | 
383  | 12  |                         ec = msgpack_errc::unexpected_eof;  | 
384  | 12  |                         more_ = false;  | 
385  | 12  |                         return;  | 
386  | 12  |                     }  | 
387  | 20.9k  |                     uint32_t val = binary::big_to_native<uint32_t>(buf, sizeof(buf));  | 
388  | 20.9k  |                     visitor.uint64_value(val, semantic_tag::none, *this, ec);  | 
389  | 20.9k  |                     more_ = !cursor_mode_;  | 
390  | 20.9k  |                     break;  | 
391  | 20.9k  |                 }  | 
392  |  |  | 
393  | 5.45k  |                 case jsoncons::msgpack::msgpack_type::uint64_type:   | 
394  | 5.45k  |                 { | 
395  | 5.45k  |                     uint8_t buf[sizeof(uint64_t)];  | 
396  | 5.45k  |                     if (source_.read(buf, sizeof(uint64_t)) != sizeof(uint64_t))  | 
397  | 15  |                     { | 
398  | 15  |                         ec = msgpack_errc::unexpected_eof;  | 
399  | 15  |                         more_ = false;  | 
400  | 15  |                         return;  | 
401  | 15  |                     }  | 
402  | 5.44k  |                     uint64_t val = binary::big_to_native<uint64_t>(buf, sizeof(buf));  | 
403  | 5.44k  |                     visitor.uint64_value(val, semantic_tag::none, *this, ec);  | 
404  | 5.44k  |                     more_ = !cursor_mode_;  | 
405  | 5.44k  |                     break;  | 
406  | 5.45k  |                 }  | 
407  |  |  | 
408  | 83.7k  |                 case jsoncons::msgpack::msgpack_type::int8_type:   | 
409  | 83.7k  |                 { | 
410  | 83.7k  |                     uint8_t buf[sizeof(int8_t)];  | 
411  | 83.7k  |                     if (source_.read(buf, sizeof(int8_t)) != sizeof(int8_t))  | 
412  | 3  |                     { | 
413  | 3  |                         ec = msgpack_errc::unexpected_eof;  | 
414  | 3  |                         more_ = false;  | 
415  | 3  |                         return;  | 
416  | 3  |                     }  | 
417  | 83.7k  |                     int8_t val = binary::big_to_native<int8_t>(buf, sizeof(buf));  | 
418  | 83.7k  |                     visitor.int64_value(val, semantic_tag::none, *this, ec);  | 
419  | 83.7k  |                     more_ = !cursor_mode_;  | 
420  | 83.7k  |                     break;  | 
421  | 83.7k  |                 }  | 
422  |  |  | 
423  | 25.2k  |                 case jsoncons::msgpack::msgpack_type::int16_type:   | 
424  | 25.2k  |                 { | 
425  | 25.2k  |                     uint8_t buf[sizeof(int16_t)];  | 
426  | 25.2k  |                     if (source_.read(buf, sizeof(int16_t)) != sizeof(int16_t))  | 
427  | 8  |                     { | 
428  | 8  |                         ec = msgpack_errc::unexpected_eof;  | 
429  | 8  |                         more_ = false;  | 
430  | 8  |                         return;  | 
431  | 8  |                     }  | 
432  | 25.2k  |                     int16_t val = binary::big_to_native<int16_t>(buf, sizeof(buf));  | 
433  | 25.2k  |                     visitor.int64_value(val, semantic_tag::none, *this, ec);  | 
434  | 25.2k  |                     more_ = !cursor_mode_;  | 
435  | 25.2k  |                     break;  | 
436  | 25.2k  |                 }  | 
437  |  |  | 
438  | 24.1k  |                 case jsoncons::msgpack::msgpack_type::int32_type:   | 
439  | 24.1k  |                 { | 
440  | 24.1k  |                     uint8_t buf[sizeof(int32_t)];  | 
441  | 24.1k  |                     if (source_.read(buf, sizeof(int32_t)) != sizeof(int32_t))  | 
442  | 13  |                     { | 
443  | 13  |                         ec = msgpack_errc::unexpected_eof;  | 
444  | 13  |                         more_ = false;  | 
445  | 13  |                         return;  | 
446  | 13  |                     }  | 
447  | 24.1k  |                     int32_t val = binary::big_to_native<int32_t>(buf, sizeof(buf));  | 
448  | 24.1k  |                     visitor.int64_value(val, semantic_tag::none, *this, ec);  | 
449  | 24.1k  |                     more_ = !cursor_mode_;  | 
450  | 24.1k  |                     break;  | 
451  | 24.1k  |                 }  | 
452  |  |  | 
453  | 20.4k  |                 case jsoncons::msgpack::msgpack_type::int64_type:   | 
454  | 20.4k  |                 { | 
455  | 20.4k  |                     uint8_t buf[sizeof(int64_t)];  | 
456  | 20.4k  |                     if (source_.read(buf, sizeof(int64_t)) != sizeof(int64_t))  | 
457  | 40  |                     { | 
458  | 40  |                         ec = msgpack_errc::unexpected_eof;  | 
459  | 40  |                         more_ = false;  | 
460  | 40  |                         return;  | 
461  | 40  |                     }  | 
462  | 20.3k  |                     int64_t val = binary::big_to_native<int64_t>(buf, sizeof(buf));  | 
463  | 20.3k  |                     visitor.int64_value(val, semantic_tag::none, *this, ec);  | 
464  | 20.3k  |                     more_ = !cursor_mode_;  | 
465  | 20.3k  |                     break;  | 
466  | 20.4k  |                 }  | 
467  |  |  | 
468  | 2.15k  |                 case jsoncons::msgpack::msgpack_type::str8_type:   | 
469  | 3.53k  |                 case jsoncons::msgpack::msgpack_type::str16_type:   | 
470  | 4.77k  |                 case jsoncons::msgpack::msgpack_type::str32_type:   | 
471  | 4.77k  |                 { | 
472  | 4.77k  |                     std::size_t len = get_size(type, ec);  | 
473  | 4.77k  |                     if (!more_)  | 
474  | 71  |                     { | 
475  | 71  |                         return;  | 
476  | 71  |                     }  | 
477  |  |  | 
478  | 4.70k  |                     text_buffer_.clear();  | 
479  | 4.70k  |                     if (source_reader<Source>::read(source_,text_buffer_,len) != static_cast<std::size_t>(len))  | 
480  | 298  |                     { | 
481  | 298  |                         ec = msgpack_errc::unexpected_eof;  | 
482  | 298  |                         more_ = false;  | 
483  | 298  |                         return;  | 
484  | 298  |                     }  | 
485  |  |  | 
486  | 4.40k  |                     auto result = unicode_traits::validate(text_buffer_.data(),text_buffer_.size());  | 
487  | 4.40k  |                     if (result.ec != unicode_traits::conv_errc())  | 
488  | 52  |                     { | 
489  | 52  |                         ec = msgpack_errc::invalid_utf8_text_string;  | 
490  | 52  |                         more_ = false;  | 
491  | 52  |                         return;  | 
492  | 52  |                     }  | 
493  | 4.35k  |                     visitor.string_value(jsoncons::basic_string_view<char>(text_buffer_.data(),text_buffer_.length()), semantic_tag::none, *this, ec);  | 
494  | 4.35k  |                     more_ = !cursor_mode_;  | 
495  | 4.35k  |                     break;  | 
496  | 4.40k  |                 }  | 
497  |  |  | 
498  | 93.8k  |                 case jsoncons::msgpack::msgpack_type::bin8_type:   | 
499  | 99.9k  |                 case jsoncons::msgpack::msgpack_type::bin16_type:   | 
500  | 101k  |                 case jsoncons::msgpack::msgpack_type::bin32_type:   | 
501  | 101k  |                 { | 
502  | 101k  |                     std::size_t len = get_size(type,ec);  | 
503  | 101k  |                     if (!more_)  | 
504  | 78  |                     { | 
505  | 78  |                         return;  | 
506  | 78  |                     }  | 
507  | 101k  |                     bytes_buffer_.clear();  | 
508  | 101k  |                     if (source_reader<Source>::read(source_,bytes_buffer_,len) != static_cast<std::size_t>(len))  | 
509  | 461  |                     { | 
510  | 461  |                         ec = msgpack_errc::unexpected_eof;  | 
511  | 461  |                         more_ = false;  | 
512  | 461  |                         return;  | 
513  | 461  |                     }  | 
514  |  |  | 
515  | 100k  |                     visitor.byte_string_value(byte_string_view(bytes_buffer_.data(),bytes_buffer_.size()),   | 
516  | 100k  |                                                       semantic_tag::none,   | 
517  | 100k  |                                                       *this,  | 
518  | 100k  |                                                       ec);  | 
519  | 100k  |                     more_ = !cursor_mode_;  | 
520  | 100k  |                     break;  | 
521  | 101k  |                 }  | 
522  | 33.3k  |                 case jsoncons::msgpack::msgpack_type::fixext1_type:   | 
523  | 170k  |                 case jsoncons::msgpack::msgpack_type::fixext2_type:   | 
524  | 176k  |                 case jsoncons::msgpack::msgpack_type::fixext4_type:   | 
525  | 269k  |                 case jsoncons::msgpack::msgpack_type::fixext8_type:   | 
526  | 280k  |                 case jsoncons::msgpack::msgpack_type::fixext16_type:   | 
527  | 322k  |                 case jsoncons::msgpack::msgpack_type::ext8_type:   | 
528  | 325k  |                 case jsoncons::msgpack::msgpack_type::ext16_type:   | 
529  | 327k  |                 case jsoncons::msgpack::msgpack_type::ext32_type:   | 
530  | 327k  |                 { | 
531  | 327k  |                     std::size_t len = get_size(type,ec);  | 
532  | 327k  |                     if (!more_)  | 
533  | 77  |                     { | 
534  | 77  |                         return;  | 
535  | 77  |                     }  | 
536  |  |  | 
537  |  |                     // type  | 
538  | 327k  |                     uint8_t buf[sizeof(int8_t)];  | 
539  | 327k  |                     if (source_.read(buf, sizeof(int8_t)) != sizeof(int8_t))  | 
540  | 142  |                     { | 
541  | 142  |                         ec = msgpack_errc::unexpected_eof;  | 
542  | 142  |                         more_ = false;  | 
543  | 142  |                         return;  | 
544  | 142  |                     }  | 
545  |  |  | 
546  | 327k  |                     int8_t ext_type = binary::big_to_native<int8_t>(buf, sizeof(buf));  | 
547  |  |  | 
548  | 327k  |                     bool is_timestamp = false;   | 
549  | 327k  |                     if (ext_type == -1)  | 
550  | 125k  |                     { | 
551  | 125k  |                         is_timestamp = true;;  | 
552  | 125k  |                     }  | 
553  |  |  | 
554  |  |                     // payload  | 
555  | 327k  |                     if (is_timestamp && len == 4)  | 
556  | 2.46k  |                     { | 
557  | 2.46k  |                         uint8_t buf32[sizeof(uint32_t)];  | 
558  | 2.46k  |                         if (source_.read(buf32, sizeof(uint32_t)) != sizeof(uint32_t))  | 
559  | 9  |                         { | 
560  | 9  |                             ec = msgpack_errc::unexpected_eof;  | 
561  | 9  |                             more_ = false;  | 
562  | 9  |                             return;  | 
563  | 9  |                         }  | 
564  | 2.45k  |                         uint32_t val = binary::big_to_native<uint32_t>(buf32, sizeof(buf32));  | 
565  | 2.45k  |                         visitor.uint64_value(val, semantic_tag::epoch_second, *this, ec);  | 
566  | 2.45k  |                         more_ = !cursor_mode_;  | 
567  | 2.45k  |                     }  | 
568  | 325k  |                     else if (is_timestamp && len == 8)  | 
569  | 87.5k  |                     { | 
570  | 87.5k  |                         uint8_t buf64[sizeof(uint64_t)];  | 
571  | 87.5k  |                         if (source_.read(buf64, sizeof(uint64_t)) != sizeof(uint64_t))  | 
572  | 27  |                         { | 
573  | 27  |                             ec = msgpack_errc::unexpected_eof;  | 
574  | 27  |                             more_ = false;  | 
575  | 27  |                             return;  | 
576  | 27  |                         }  | 
577  | 87.5k  |                         uint64_t data64 = binary::big_to_native<uint64_t>(buf64, sizeof(buf64));  | 
578  | 87.5k  |                         uint64_t sec = data64 & 0x00000003ffffffffL;  | 
579  | 87.5k  |                         uint64_t nsec = data64 >> 34;  | 
580  |  |  | 
581  | 87.5k  |                         bigint nano(sec);  | 
582  | 87.5k  |                         nano *= uint64_t(nanos_in_second);  | 
583  | 87.5k  |                         nano += nsec;  | 
584  | 87.5k  |                         text_buffer_.clear();  | 
585  | 87.5k  |                         nano.write_string(text_buffer_);  | 
586  | 87.5k  |                         visitor.string_value(text_buffer_, semantic_tag::epoch_nano, *this, ec);  | 
587  | 87.5k  |                         more_ = !cursor_mode_;  | 
588  | 87.5k  |                         if (!more_) return;  | 
589  | 87.5k  |                     }  | 
590  | 237k  |                     else if (is_timestamp && len == 12)  | 
591  | 32.2k  |                     { | 
592  | 32.2k  |                         uint8_t buf1[sizeof(uint32_t)];  | 
593  | 32.2k  |                         if (source_.read(buf1, sizeof(uint32_t)) != sizeof(uint32_t))  | 
594  | 8  |                         { | 
595  | 8  |                             ec = msgpack_errc::unexpected_eof;  | 
596  | 8  |                             more_ = false;  | 
597  | 8  |                             return;  | 
598  | 8  |                         }  | 
599  | 32.2k  |                         uint32_t nsec = binary::big_to_native<uint32_t>(buf1, sizeof(buf1));  | 
600  |  |  | 
601  | 32.2k  |                         uint8_t buf2[sizeof(int64_t)];  | 
602  | 32.2k  |                         if (source_.read(buf2, sizeof(int64_t)) != sizeof(int64_t))  | 
603  | 14  |                         { | 
604  | 14  |                             ec = msgpack_errc::unexpected_eof;  | 
605  | 14  |                             more_ = false;  | 
606  | 14  |                             return;  | 
607  | 14  |                         }  | 
608  | 32.2k  |                         int64_t sec = binary::big_to_native<int64_t>(buf2, sizeof(buf2));  | 
609  |  |  | 
610  | 32.2k  |                         bigint nano(sec);  | 
611  |  |  | 
612  | 32.2k  |                         nano *= uint64_t(nanos_in_second);  | 
613  |  |  | 
614  | 32.2k  |                         if (nano < 0)  | 
615  | 10.6k  |                         { | 
616  | 10.6k  |                             nano -= nsec;  | 
617  | 10.6k  |                         }  | 
618  | 21.5k  |                         else  | 
619  | 21.5k  |                         { | 
620  | 21.5k  |                             nano += nsec;  | 
621  | 21.5k  |                         }  | 
622  |  |  | 
623  | 32.2k  |                         text_buffer_.clear();  | 
624  | 32.2k  |                         nano.write_string(text_buffer_);  | 
625  | 32.2k  |                         visitor.string_value(text_buffer_, semantic_tag::epoch_nano, *this, ec);  | 
626  | 32.2k  |                         more_ = !cursor_mode_;  | 
627  | 32.2k  |                         if (!more_) return;  | 
628  | 32.2k  |                     }  | 
629  | 205k  |                     else  | 
630  | 205k  |                     { | 
631  | 205k  |                         bytes_buffer_.clear();  | 
632  | 205k  |                         if (source_reader<Source>::read(source_,bytes_buffer_,len) != static_cast<std::size_t>(len))  | 
633  | 443  |                         { | 
634  | 443  |                             ec = msgpack_errc::unexpected_eof;  | 
635  | 443  |                             more_ = false;  | 
636  | 443  |                             return;  | 
637  | 443  |                         }  | 
638  |  |  | 
639  | 204k  |                         visitor.byte_string_value(byte_string_view(bytes_buffer_.data(),bytes_buffer_.size()),   | 
640  | 204k  |                                                           static_cast<uint8_t>(ext_type),   | 
641  | 204k  |                                                           *this,  | 
642  | 204k  |                                                           ec);  | 
643  | 204k  |                         more_ = !cursor_mode_;  | 
644  | 204k  |                     }  | 
645  | 327k  |                     break;  | 
646  | 327k  |                 }  | 
647  |  |  | 
648  | 327k  |                 case jsoncons::msgpack::msgpack_type::array16_type:   | 
649  | 14.0k  |                 case jsoncons::msgpack::msgpack_type::array32_type:   | 
650  | 14.0k  |                 { | 
651  | 14.0k  |                     begin_array(visitor,type,ec);  | 
652  | 14.0k  |                     break;  | 
653  | 9.76k  |                 }  | 
654  |  |  | 
655  | 14.5k  |                 case jsoncons::msgpack::msgpack_type::map16_type :   | 
656  | 17.7k  |                 case jsoncons::msgpack::msgpack_type::map32_type :   | 
657  | 17.7k  |                 { | 
658  | 17.7k  |                     begin_object(visitor, type, ec);  | 
659  | 17.7k  |                     break;  | 
660  | 14.5k  |                 }  | 
661  |  |  | 
662  | 43  |                 default:  | 
663  | 43  |                 { | 
664  | 43  |                     ec = msgpack_errc::unknown_type;  | 
665  | 43  |                     more_ = false;  | 
666  | 43  |                     return;  | 
667  | 14.5k  |                 }  | 
668  | 64.6M  |             }  | 
669  | 64.6M  |         }  | 
670  | 139M  |     }  | 
671  |  |  | 
672  |  |     void begin_array(item_event_visitor& visitor, uint8_t type, std::error_code& ec)  | 
673  | 9.18M  |     { | 
674  | 9.18M  |         if (JSONCONS_UNLIKELY(++nesting_depth_ > options_.max_nesting_depth()))  | 
675  | 8  |         { | 
676  | 8  |             ec = msgpack_errc::max_nesting_depth_exceeded;  | 
677  | 8  |             more_ = false;  | 
678  | 8  |             return;  | 
679  | 8  |         }   | 
680  | 9.18M  |         std::size_t length = get_size(type, ec);  | 
681  | 9.18M  |         if (!more_)  | 
682  | 55  |         { | 
683  | 55  |             return;  | 
684  | 55  |         }  | 
685  | 9.18M  |         state_stack_.emplace_back(parse_mode::array,length);  | 
686  | 9.18M  |         visitor.begin_array(length, semantic_tag::none, *this, ec);  | 
687  | 9.18M  |         more_ = !cursor_mode_;  | 
688  | 9.18M  |     }  | 
689  |  |  | 
690  |  |     void end_array(item_event_visitor& visitor, std::error_code& ec)  | 
691  | 9.09M  |     { | 
692  | 9.09M  |         --nesting_depth_;  | 
693  |  |  | 
694  | 9.09M  |         visitor.end_array(*this, ec);  | 
695  | 9.09M  |         more_ = !cursor_mode_;  | 
696  | 9.09M  |         state_stack_.pop_back();  | 
697  | 9.09M  |     }  | 
698  |  |  | 
699  |  |     void begin_object(item_event_visitor& visitor, uint8_t type, std::error_code& ec)  | 
700  | 5.92M  |     { | 
701  | 5.92M  |         if (JSONCONS_UNLIKELY(++nesting_depth_ > options_.max_nesting_depth()))  | 
702  | 5  |         { | 
703  | 5  |             ec = msgpack_errc::max_nesting_depth_exceeded;  | 
704  | 5  |             more_ = false;  | 
705  | 5  |             return;  | 
706  | 5  |         }   | 
707  | 5.92M  |         std::size_t length = get_size(type, ec);  | 
708  | 5.92M  |         if (!more_)  | 
709  | 55  |         { | 
710  | 55  |             return;  | 
711  | 55  |         }  | 
712  | 5.92M  |         state_stack_.emplace_back(parse_mode::map_key,length);  | 
713  | 5.92M  |         visitor.begin_object(length, semantic_tag::none, *this, ec);  | 
714  | 5.92M  |         more_ = !cursor_mode_;  | 
715  | 5.92M  |     }  | 
716  |  |  | 
717  |  |     void end_object(item_event_visitor& visitor, std::error_code& ec)  | 
718  | 5.87M  |     { | 
719  | 5.87M  |         --nesting_depth_;  | 
720  | 5.87M  |         visitor.end_object(*this, ec);  | 
721  | 5.87M  |         more_ = !cursor_mode_;  | 
722  | 5.87M  |         state_stack_.pop_back();  | 
723  | 5.87M  |     }  | 
724  |  |  | 
725  |  |     std::size_t get_size(uint8_t type, std::error_code& ec)  | 
726  | 15.5M  |     { | 
727  | 15.5M  |         switch (type)  | 
728  | 15.5M  |         { | 
729  | 2.15k  |             case jsoncons::msgpack::msgpack_type::str8_type:   | 
730  | 95.9k  |             case jsoncons::msgpack::msgpack_type::bin8_type:   | 
731  | 137k  |             case jsoncons::msgpack::msgpack_type::ext8_type:   | 
732  | 137k  |             { | 
733  | 137k  |                 uint8_t buf[sizeof(int8_t)];  | 
734  | 137k  |                 if (source_.read(buf, sizeof(int8_t)) != sizeof(int8_t))  | 
735  | 77  |                 { | 
736  | 77  |                     ec = msgpack_errc::unexpected_eof;  | 
737  | 77  |                     more_ = false;  | 
738  | 77  |                     return 0;  | 
739  | 77  |                 }  | 
740  | 137k  |                 uint8_t len = binary::big_to_native<uint8_t>(buf, sizeof(buf));  | 
741  | 137k  |                 return static_cast<std::size_t>(len);  | 
742  | 137k  |             }  | 
743  |  |  | 
744  | 1.37k  |             case jsoncons::msgpack::msgpack_type::str16_type:   | 
745  | 7.56k  |             case jsoncons::msgpack::msgpack_type::bin16_type:   | 
746  | 10.1k  |             case jsoncons::msgpack::msgpack_type::ext16_type:   | 
747  | 19.8k  |             case jsoncons::msgpack::msgpack_type::array16_type:   | 
748  | 34.4k  |             case jsoncons::msgpack::msgpack_type::map16_type:  | 
749  | 34.4k  |             { | 
750  | 34.4k  |                 uint8_t buf[sizeof(int16_t)];  | 
751  | 34.4k  |                 if (source_.read(buf, sizeof(int16_t)) != sizeof(int16_t))  | 
752  | 130  |                 { | 
753  | 130  |                     ec = msgpack_errc::unexpected_eof;  | 
754  | 130  |                     more_ = false;  | 
755  | 130  |                     return 0;  | 
756  | 130  |                 }  | 
757  | 34.2k  |                 uint16_t len = binary::big_to_native<uint16_t>(buf, sizeof(buf));  | 
758  | 34.2k  |                 return static_cast<std::size_t>(len);  | 
759  | 34.4k  |             }  | 
760  |  |  | 
761  | 1.23k  |             case jsoncons::msgpack::msgpack_type::str32_type:   | 
762  | 2.47k  |             case jsoncons::msgpack::msgpack_type::bin32_type:   | 
763  | 4.93k  |             case jsoncons::msgpack::msgpack_type::ext32_type:   | 
764  | 9.18k  |             case jsoncons::msgpack::msgpack_type::array32_type:   | 
765  | 12.3k  |             case jsoncons::msgpack::msgpack_type::map32_type :   | 
766  | 12.3k  |             { | 
767  | 12.3k  |                 uint8_t buf[sizeof(int32_t)];  | 
768  | 12.3k  |                 if (source_.read(buf, sizeof(int32_t)) != sizeof(int32_t))  | 
769  | 129  |                 { | 
770  | 129  |                     ec = msgpack_errc::unexpected_eof;  | 
771  | 129  |                     more_ = false;  | 
772  | 129  |                     return 0;  | 
773  | 129  |                 }  | 
774  | 12.2k  |                 uint32_t len = binary::big_to_native<uint32_t>(buf, sizeof(buf));  | 
775  | 12.2k  |                 return static_cast<std::size_t>(len);  | 
776  | 12.3k  |             }  | 
777  | 33.3k  |             case jsoncons::msgpack::msgpack_type::fixext1_type:   | 
778  | 33.3k  |                 return 1;  | 
779  | 136k  |             case jsoncons::msgpack::msgpack_type::fixext2_type:   | 
780  | 136k  |                 return 2;  | 
781  | 6.47k  |             case jsoncons::msgpack::msgpack_type::fixext4_type:   | 
782  | 6.47k  |                 return 4;  | 
783  | 93.2k  |             case jsoncons::msgpack::msgpack_type::fixext8_type:   | 
784  | 93.2k  |                 return 8;  | 
785  | 11.0k  |             case jsoncons::msgpack::msgpack_type::fixext16_type:   | 
786  | 11.0k  |                 return 16;  | 
787  | 15.0M  |             default:  | 
788  | 15.0M  |                 if ((type > 0x8f && type <= 0x9f) // fixarray  | 
789  | 5.91M  |                     || (type > 0x7f && type <= 0x8f) // fixmap  | 
790  | 15.0M  |         )  | 
791  | 15.0M  |                 { | 
792  | 15.0M  |                     return type & 0x0f;  | 
793  | 15.0M  |                 }  | 
794  | 0  |                 else  | 
795  | 0  |                 { | 
796  | 0  |                     ec = msgpack_errc::unknown_type;  | 
797  | 0  |                     more_ = false;  | 
798  | 0  |                     return 0;  | 
799  | 0  |                 }  | 
800  | 0  |                 break;  | 
801  | 15.5M  |         }  | 
802  | 15.5M  |     }  | 
803  |  | };  | 
804  |  |  | 
805  |  | } // namespace msgpack  | 
806  |  | } // namespace jsoncons  | 
807  |  |  | 
808  |  | #endif // JSONCONS_EXT_MSGPACK_MSGPACK_PARSER_HPP  |