jsoncons 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (155) hide show
  1. checksums.yaml +7 -0
  2. data/ext/jsoncons/extconf.rb +43 -0
  3. data/ext/jsoncons/jsoncons.cpp +161 -0
  4. data/ext/jsoncons/jsoncons.h +10 -0
  5. data/jsoncons.gemspec +44 -0
  6. data/lib/jsoncons/jsoncons/examples/input/address-book.json +13 -0
  7. data/lib/jsoncons/jsoncons/examples/input/books.json +28 -0
  8. data/lib/jsoncons/jsoncons/examples/input/countries.json +7 -0
  9. data/lib/jsoncons/jsoncons/examples/input/employees.json +30 -0
  10. data/lib/jsoncons/jsoncons/examples/input/jsonschema/name.json +15 -0
  11. data/lib/jsoncons/jsoncons/examples/input/multiple-json-objects.json +3 -0
  12. data/lib/jsoncons/jsoncons/examples/input/sales.csv +6 -0
  13. data/lib/jsoncons/jsoncons/examples/input/store.json +28 -0
  14. data/lib/jsoncons/jsoncons/examples/input/tasks.csv +6 -0
  15. data/lib/jsoncons/jsoncons/include/jsoncons/allocator_holder.hpp +38 -0
  16. data/lib/jsoncons/jsoncons/include/jsoncons/basic_json.hpp +5905 -0
  17. data/lib/jsoncons/jsoncons/include/jsoncons/bigint.hpp +1611 -0
  18. data/lib/jsoncons/jsoncons/include/jsoncons/byte_string.hpp +820 -0
  19. data/lib/jsoncons/jsoncons/include/jsoncons/config/binary_config.hpp +226 -0
  20. data/lib/jsoncons/jsoncons/include/jsoncons/config/compiler_support.hpp +375 -0
  21. data/lib/jsoncons/jsoncons/include/jsoncons/config/jsoncons_config.hpp +309 -0
  22. data/lib/jsoncons/jsoncons/include/jsoncons/config/version.hpp +40 -0
  23. data/lib/jsoncons/jsoncons/include/jsoncons/conv_error.hpp +218 -0
  24. data/lib/jsoncons/jsoncons/include/jsoncons/decode_json.hpp +209 -0
  25. data/lib/jsoncons/jsoncons/include/jsoncons/decode_traits.hpp +651 -0
  26. data/lib/jsoncons/jsoncons/include/jsoncons/detail/endian.hpp +44 -0
  27. data/lib/jsoncons/jsoncons/include/jsoncons/detail/grisu3.hpp +312 -0
  28. data/lib/jsoncons/jsoncons/include/jsoncons/detail/optional.hpp +483 -0
  29. data/lib/jsoncons/jsoncons/include/jsoncons/detail/parse_number.hpp +1133 -0
  30. data/lib/jsoncons/jsoncons/include/jsoncons/detail/span.hpp +188 -0
  31. data/lib/jsoncons/jsoncons/include/jsoncons/detail/string_view.hpp +537 -0
  32. data/lib/jsoncons/jsoncons/include/jsoncons/detail/string_wrapper.hpp +370 -0
  33. data/lib/jsoncons/jsoncons/include/jsoncons/detail/write_number.hpp +567 -0
  34. data/lib/jsoncons/jsoncons/include/jsoncons/encode_json.hpp +315 -0
  35. data/lib/jsoncons/jsoncons/include/jsoncons/encode_traits.hpp +378 -0
  36. data/lib/jsoncons/jsoncons/include/jsoncons/json.hpp +18 -0
  37. data/lib/jsoncons/jsoncons/include/jsoncons/json_array.hpp +324 -0
  38. data/lib/jsoncons/jsoncons/include/jsoncons/json_content_handler.hpp +12 -0
  39. data/lib/jsoncons/jsoncons/include/jsoncons/json_cursor.hpp +448 -0
  40. data/lib/jsoncons/jsoncons/include/jsoncons/json_decoder.hpp +420 -0
  41. data/lib/jsoncons/jsoncons/include/jsoncons/json_encoder.hpp +1587 -0
  42. data/lib/jsoncons/jsoncons/include/jsoncons/json_error.hpp +156 -0
  43. data/lib/jsoncons/jsoncons/include/jsoncons/json_exception.hpp +241 -0
  44. data/lib/jsoncons/jsoncons/include/jsoncons/json_filter.hpp +653 -0
  45. data/lib/jsoncons/jsoncons/include/jsoncons/json_fwd.hpp +23 -0
  46. data/lib/jsoncons/jsoncons/include/jsoncons/json_object.hpp +1772 -0
  47. data/lib/jsoncons/jsoncons/include/jsoncons/json_options.hpp +862 -0
  48. data/lib/jsoncons/jsoncons/include/jsoncons/json_parser.hpp +2900 -0
  49. data/lib/jsoncons/jsoncons/include/jsoncons/json_reader.hpp +731 -0
  50. data/lib/jsoncons/jsoncons/include/jsoncons/json_traits_macros.hpp +1072 -0
  51. data/lib/jsoncons/jsoncons/include/jsoncons/json_traits_macros_deprecated.hpp +144 -0
  52. data/lib/jsoncons/jsoncons/include/jsoncons/json_type.hpp +206 -0
  53. data/lib/jsoncons/jsoncons/include/jsoncons/json_type_traits.hpp +1830 -0
  54. data/lib/jsoncons/jsoncons/include/jsoncons/json_visitor.hpp +1560 -0
  55. data/lib/jsoncons/jsoncons/include/jsoncons/json_visitor2.hpp +2079 -0
  56. data/lib/jsoncons/jsoncons/include/jsoncons/pretty_print.hpp +89 -0
  57. data/lib/jsoncons/jsoncons/include/jsoncons/ser_context.hpp +62 -0
  58. data/lib/jsoncons/jsoncons/include/jsoncons/sink.hpp +289 -0
  59. data/lib/jsoncons/jsoncons/include/jsoncons/source.hpp +777 -0
  60. data/lib/jsoncons/jsoncons/include/jsoncons/source_adaptor.hpp +148 -0
  61. data/lib/jsoncons/jsoncons/include/jsoncons/staj2_cursor.hpp +1189 -0
  62. data/lib/jsoncons/jsoncons/include/jsoncons/staj_cursor.hpp +1254 -0
  63. data/lib/jsoncons/jsoncons/include/jsoncons/staj_iterator.hpp +449 -0
  64. data/lib/jsoncons/jsoncons/include/jsoncons/tag_type.hpp +245 -0
  65. data/lib/jsoncons/jsoncons/include/jsoncons/text_source_adaptor.hpp +144 -0
  66. data/lib/jsoncons/jsoncons/include/jsoncons/traits_extension.hpp +884 -0
  67. data/lib/jsoncons/jsoncons/include/jsoncons/typed_array_view.hpp +250 -0
  68. data/lib/jsoncons/jsoncons/include/jsoncons/unicode_traits.hpp +1330 -0
  69. data/lib/jsoncons/jsoncons/include/jsoncons/uri.hpp +635 -0
  70. data/lib/jsoncons/jsoncons/include/jsoncons/value_converter.hpp +340 -0
  71. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson.hpp +23 -0
  72. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_cursor.hpp +320 -0
  73. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_decimal128.hpp +865 -0
  74. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_encoder.hpp +585 -0
  75. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_error.hpp +103 -0
  76. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_oid.hpp +245 -0
  77. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_options.hpp +75 -0
  78. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_parser.hpp +645 -0
  79. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_reader.hpp +92 -0
  80. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_type.hpp +44 -0
  81. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/decode_bson.hpp +201 -0
  82. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/encode_bson.hpp +144 -0
  83. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor.hpp +26 -0
  84. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_cursor.hpp +351 -0
  85. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_cursor2.hpp +265 -0
  86. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_detail.hpp +93 -0
  87. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_encoder.hpp +1766 -0
  88. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_error.hpp +105 -0
  89. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_options.hpp +113 -0
  90. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_parser.hpp +1942 -0
  91. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_reader.hpp +116 -0
  92. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/decode_cbor.hpp +203 -0
  93. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/encode_cbor.hpp +151 -0
  94. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv.hpp +17 -0
  95. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_cursor.hpp +358 -0
  96. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_encoder.hpp +954 -0
  97. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_error.hpp +85 -0
  98. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_options.hpp +973 -0
  99. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_parser.hpp +2099 -0
  100. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_reader.hpp +348 -0
  101. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_serializer.hpp +12 -0
  102. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/decode_csv.hpp +208 -0
  103. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/encode_csv.hpp +122 -0
  104. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jmespath/jmespath.hpp +5215 -0
  105. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jmespath/jmespath_error.hpp +215 -0
  106. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpatch/jsonpatch.hpp +579 -0
  107. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpatch/jsonpatch_error.hpp +121 -0
  108. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/expression.hpp +3329 -0
  109. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/flatten.hpp +432 -0
  110. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/json_location.hpp +445 -0
  111. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/json_query.hpp +115 -0
  112. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/jsonpath.hpp +13 -0
  113. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/jsonpath_error.hpp +240 -0
  114. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/jsonpath_expression.hpp +2612 -0
  115. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/jsonpath_selector.hpp +1322 -0
  116. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpointer/jsonpointer.hpp +1577 -0
  117. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpointer/jsonpointer_error.hpp +119 -0
  118. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/format_validator.hpp +968 -0
  119. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/json_validator.hpp +120 -0
  120. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/jsonschema.hpp +13 -0
  121. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/jsonschema_error.hpp +105 -0
  122. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/jsonschema_version.hpp +18 -0
  123. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/keyword_validator.hpp +1745 -0
  124. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/keyword_validator_factory.hpp +556 -0
  125. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/schema_draft7.hpp +198 -0
  126. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/schema_location.hpp +200 -0
  127. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/schema_version.hpp +35 -0
  128. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/subschema.hpp +144 -0
  129. data/lib/jsoncons/jsoncons/include/jsoncons_ext/mergepatch/mergepatch.hpp +103 -0
  130. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/decode_msgpack.hpp +202 -0
  131. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/encode_msgpack.hpp +142 -0
  132. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack.hpp +24 -0
  133. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_cursor.hpp +343 -0
  134. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_cursor2.hpp +259 -0
  135. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_encoder.hpp +753 -0
  136. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_error.hpp +94 -0
  137. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_options.hpp +74 -0
  138. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_parser.hpp +748 -0
  139. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_reader.hpp +116 -0
  140. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_type.hpp +63 -0
  141. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/decode_ubjson.hpp +201 -0
  142. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/encode_ubjson.hpp +142 -0
  143. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson.hpp +23 -0
  144. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_cursor.hpp +307 -0
  145. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_encoder.hpp +502 -0
  146. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_error.hpp +100 -0
  147. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_options.hpp +87 -0
  148. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_parser.hpp +880 -0
  149. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_reader.hpp +92 -0
  150. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_type.hpp +43 -0
  151. data/lib/jsoncons/version.rb +5 -0
  152. data/lib/jsoncons.rb +33 -0
  153. data/test/jsoncons_test.rb +108 -0
  154. data/test/test_helper.rb +7 -0
  155. metadata +268 -0
@@ -0,0 +1,645 @@
1
+ // Copyright 2017 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_BSON_BSON_PARSER_HPP
8
+ #define JSONCONS_BSON_BSON_PARSER_HPP
9
+
10
+ #include <string>
11
+ #include <vector>
12
+ #include <memory>
13
+ #include <utility> // std::move
14
+ #include <jsoncons/json.hpp>
15
+ #include <jsoncons/source.hpp>
16
+ #include <jsoncons/json_visitor.hpp>
17
+ #include <jsoncons/config/jsoncons_config.hpp>
18
+ #include <jsoncons_ext/bson/bson_type.hpp>
19
+ #include <jsoncons_ext/bson/bson_decimal128.hpp>
20
+ #include <jsoncons_ext/bson/bson_error.hpp>
21
+ #include <jsoncons_ext/bson/bson_options.hpp>
22
+ #include <jsoncons_ext/bson/bson_oid.hpp>
23
+
24
+ namespace jsoncons { namespace bson {
25
+
26
+ enum class parse_mode {root,accept,document,array,value};
27
+
28
+ struct parse_state
29
+ {
30
+ parse_mode mode;
31
+ std::size_t length;
32
+ std::size_t pos;
33
+ uint8_t type;
34
+ std::size_t index;
35
+
36
+ parse_state(parse_mode mode_, std::size_t length_, std::size_t pos_, uint8_t type_ = 0) noexcept
37
+ : mode(mode_), length(length_), pos(pos_), type(type_), index(0)
38
+ {
39
+ }
40
+
41
+ parse_state(const parse_state&) = default;
42
+ parse_state(parse_state&&) = default;
43
+ parse_state& operator=(const parse_state&) = default;
44
+ parse_state& operator=(parse_state&&) = default;
45
+ };
46
+
47
+ template <class Source,class Allocator=std::allocator<char>>
48
+ class basic_bson_parser : public ser_context
49
+ {
50
+ using char_type = char;
51
+ using char_traits_type = std::char_traits<char>;
52
+ using temp_allocator_type = Allocator;
53
+ using char_allocator_type = typename std::allocator_traits<temp_allocator_type>:: template rebind_alloc<char_type>;
54
+ using byte_allocator_type = typename std::allocator_traits<temp_allocator_type>:: template rebind_alloc<uint8_t>;
55
+ using parse_state_allocator_type = typename std::allocator_traits<temp_allocator_type>:: template rebind_alloc<parse_state>;
56
+
57
+ Source source_;
58
+ bson_decode_options options_;
59
+ bool more_;
60
+ bool done_;
61
+ std::vector<uint8_t,byte_allocator_type> bytes_buffer_;
62
+ std::basic_string<char,std::char_traits<char>,char_allocator_type> text_buffer_;
63
+ std::vector<parse_state,parse_state_allocator_type> state_stack_;
64
+ public:
65
+ template <class Sourceable>
66
+ basic_bson_parser(Sourceable&& source,
67
+ const bson_decode_options& options = bson_decode_options(),
68
+ const Allocator alloc = Allocator())
69
+ : source_(std::forward<Sourceable>(source)),
70
+ options_(options),
71
+ more_(true),
72
+ done_(false),
73
+ text_buffer_(alloc),
74
+ state_stack_(alloc)
75
+ {
76
+ state_stack_.emplace_back(parse_mode::root,0,0);
77
+ }
78
+
79
+ void restart()
80
+ {
81
+ more_ = true;
82
+ }
83
+
84
+ void reset()
85
+ {
86
+ more_ = true;
87
+ done_ = false;
88
+ bytes_buffer_.clear();
89
+ text_buffer_.clear();
90
+ state_stack_.clear();
91
+ state_stack_.emplace_back(parse_mode::root,0,0);
92
+ }
93
+
94
+ template <class Sourceable>
95
+ void reset(Sourceable&& source)
96
+ {
97
+ source_ = std::forward<Sourceable>(source);
98
+ reset();
99
+ }
100
+
101
+ bool done() const
102
+ {
103
+ return done_;
104
+ }
105
+
106
+ bool stopped() const
107
+ {
108
+ return !more_;
109
+ }
110
+
111
+ std::size_t line() const override
112
+ {
113
+ return 0;
114
+ }
115
+
116
+ std::size_t column() const override
117
+ {
118
+ return source_.position();
119
+ }
120
+
121
+ void array_expected(json_visitor& visitor, std::error_code& ec)
122
+ {
123
+ if (state_stack_.size() == 2 && state_stack_.back().mode == parse_mode::document)
124
+ {
125
+ state_stack_.back().mode = parse_mode::array;
126
+ more_ = visitor.begin_array(semantic_tag::none, *this, ec);
127
+ }
128
+ }
129
+
130
+ void parse(json_visitor& visitor, std::error_code& ec)
131
+ {
132
+ if (JSONCONS_UNLIKELY(source_.is_error()))
133
+ {
134
+ ec = bson_errc::source_error;
135
+ more_ = false;
136
+ return;
137
+ }
138
+
139
+ while (!done_ && more_)
140
+ {
141
+ switch (state_stack_.back().mode)
142
+ {
143
+ case parse_mode::root:
144
+ state_stack_.back().mode = parse_mode::accept;
145
+ begin_document(visitor, ec);
146
+ break;
147
+ case parse_mode::document:
148
+ {
149
+ uint8_t type;
150
+ std::size_t n = source_.read(&type, 1);
151
+ state_stack_.back().pos += n;
152
+ if (JSONCONS_UNLIKELY(n != 1))
153
+ {
154
+ ec = bson_errc::unexpected_eof;
155
+ more_ = false;
156
+ return;
157
+ }
158
+ if (type != 0x00)
159
+ {
160
+ read_e_name(visitor,jsoncons::bson::bson_container_type::document,ec);
161
+ state_stack_.back().mode = parse_mode::value;
162
+ state_stack_.back().type = type;
163
+ }
164
+ else
165
+ {
166
+ end_document(visitor,ec);
167
+ }
168
+ break;
169
+ }
170
+ case parse_mode::array:
171
+ {
172
+ uint8_t type;
173
+ std::size_t n = source_.read(&type, 1);
174
+ state_stack_.back().pos += n;
175
+ if (JSONCONS_UNLIKELY(n != 1))
176
+ {
177
+ ec = bson_errc::unexpected_eof;
178
+ more_ = false;
179
+ return;
180
+ }
181
+ if (type != 0x00)
182
+ {
183
+ read_e_name(visitor,jsoncons::bson::bson_container_type::array,ec);
184
+ read_value(visitor, type, ec);
185
+ }
186
+ else
187
+ {
188
+ end_array(visitor,ec);
189
+ }
190
+ break;
191
+ }
192
+ case parse_mode::value:
193
+ state_stack_.back().mode = parse_mode::document;
194
+ read_value(visitor,state_stack_.back().type,ec);
195
+ break;
196
+ case parse_mode::accept:
197
+ {
198
+ JSONCONS_ASSERT(state_stack_.size() == 1);
199
+ state_stack_.clear();
200
+ more_ = false;
201
+ done_ = true;
202
+ visitor.flush();
203
+ break;
204
+ }
205
+ }
206
+ }
207
+ }
208
+
209
+ private:
210
+
211
+ void begin_document(json_visitor& visitor, std::error_code& ec)
212
+ {
213
+ if (JSONCONS_UNLIKELY(static_cast<int>(state_stack_.size()) > options_.max_nesting_depth()))
214
+ {
215
+ ec = bson_errc::max_nesting_depth_exceeded;
216
+ more_ = false;
217
+ return;
218
+ }
219
+
220
+ uint8_t buf[sizeof(int32_t)];
221
+ size_t n = source_.read(buf, sizeof(int32_t));
222
+ if (JSONCONS_UNLIKELY(n != sizeof(int32_t)))
223
+ {
224
+ ec = bson_errc::unexpected_eof;
225
+ more_ = false;
226
+ return;
227
+ }
228
+
229
+ auto length = binary::little_to_native<int32_t>(buf, sizeof(buf));
230
+
231
+ more_ = visitor.begin_object(semantic_tag::none, *this, ec);
232
+ state_stack_.emplace_back(parse_mode::document,length,n);
233
+ }
234
+
235
+ void end_document(json_visitor& visitor, std::error_code& ec)
236
+ {
237
+ JSONCONS_ASSERT(state_stack_.size() >= 2);
238
+
239
+ more_ = visitor.end_object(*this,ec);
240
+ if (JSONCONS_UNLIKELY(state_stack_.back().pos != state_stack_.back().length))
241
+ {
242
+ ec = bson_errc::size_mismatch;
243
+ more_ = false;
244
+ return;
245
+ }
246
+ std::size_t pos = state_stack_.back().pos;
247
+ state_stack_.pop_back();
248
+ state_stack_.back().pos += pos;
249
+ }
250
+
251
+ void begin_array(json_visitor& visitor, std::error_code& ec)
252
+ {
253
+ if (JSONCONS_UNLIKELY(static_cast<int>(state_stack_.size()) > options_.max_nesting_depth()))
254
+ {
255
+ ec = bson_errc::max_nesting_depth_exceeded;
256
+ more_ = false;
257
+ return;
258
+ }
259
+ uint8_t buf[sizeof(int32_t)];
260
+ std::size_t n = source_.read(buf, sizeof(int32_t));
261
+ if (JSONCONS_UNLIKELY(n != sizeof(int32_t)))
262
+ {
263
+ ec = bson_errc::unexpected_eof;
264
+ more_ = false;
265
+ return;
266
+ }
267
+ auto length = binary::little_to_native<int32_t>(buf, sizeof(buf));
268
+
269
+ more_ = visitor.begin_array(semantic_tag::none, *this, ec);
270
+ if (ec)
271
+ {
272
+ return;
273
+ }
274
+ state_stack_.emplace_back(parse_mode::array, length, n);
275
+ }
276
+
277
+ void end_array(json_visitor& visitor, std::error_code& ec)
278
+ {
279
+ JSONCONS_ASSERT(state_stack_.size() >= 2);
280
+
281
+ more_ = visitor.end_array(*this, ec);
282
+ if (JSONCONS_UNLIKELY(state_stack_.back().pos != state_stack_.back().length))
283
+ {
284
+ ec = bson_errc::size_mismatch;
285
+ more_ = false;
286
+ return;
287
+ }
288
+ std::size_t pos = state_stack_.back().pos;
289
+ state_stack_.pop_back();
290
+ state_stack_.back().pos += pos;
291
+ }
292
+
293
+ void read_e_name(json_visitor& visitor, jsoncons::bson::bson_container_type type, std::error_code& ec)
294
+ {
295
+ text_buffer_.clear();
296
+ read_cstring(ec);
297
+ if (ec)
298
+ {
299
+ return;
300
+ }
301
+ if (type == jsoncons::bson::bson_container_type::document)
302
+ {
303
+ auto result = unicode_traits::validate(text_buffer_.data(),text_buffer_.size());
304
+ if (JSONCONS_UNLIKELY(result.ec != unicode_traits::conv_errc()))
305
+ {
306
+ ec = bson_errc::invalid_utf8_text_string;
307
+ more_ = false;
308
+ return;
309
+ }
310
+ more_ = visitor.key(jsoncons::basic_string_view<char>(text_buffer_.data(),text_buffer_.length()), *this, ec);
311
+ }
312
+ }
313
+
314
+ void read_value(json_visitor& visitor, uint8_t type, std::error_code& ec)
315
+ {
316
+ switch (type)
317
+ {
318
+ case jsoncons::bson::bson_type::double_type:
319
+ {
320
+ uint8_t buf[sizeof(double)];
321
+ std::size_t n = source_.read(buf, sizeof(double));
322
+ state_stack_.back().pos += n;
323
+ if (JSONCONS_UNLIKELY(n != sizeof(double)))
324
+ {
325
+ ec = bson_errc::unexpected_eof;
326
+ more_ = false;
327
+ return;
328
+ }
329
+ double res = binary::little_to_native<double>(buf, sizeof(buf));
330
+ more_ = visitor.double_value(res, semantic_tag::none, *this, ec);
331
+ break;
332
+ }
333
+ case jsoncons::bson::bson_type::symbol_type:
334
+ case jsoncons::bson::bson_type::min_key_type:
335
+ case jsoncons::bson::bson_type::max_key_type:
336
+ case jsoncons::bson::bson_type::string_type:
337
+ {
338
+ text_buffer_.clear();
339
+ read_string(ec);
340
+ if (ec)
341
+ {
342
+ return;
343
+ }
344
+ auto result = unicode_traits::validate(text_buffer_.data(), text_buffer_.size());
345
+ if (JSONCONS_UNLIKELY(result.ec != unicode_traits::conv_errc()))
346
+ {
347
+ ec = bson_errc::invalid_utf8_text_string;
348
+ more_ = false;
349
+ return;
350
+ }
351
+ more_ = visitor.string_value(text_buffer_, semantic_tag::none, *this, ec);
352
+ break;
353
+ }
354
+ case jsoncons::bson::bson_type::javascript_type:
355
+ {
356
+ text_buffer_.clear();
357
+ read_string(ec);
358
+ if (ec)
359
+ {
360
+ return;
361
+ }
362
+ auto result = unicode_traits::validate(text_buffer_.data(), text_buffer_.size());
363
+ if (JSONCONS_UNLIKELY(result.ec != unicode_traits::conv_errc()))
364
+ {
365
+ ec = bson_errc::invalid_utf8_text_string;
366
+ more_ = false;
367
+ return;
368
+ }
369
+ more_ = visitor.string_value(text_buffer_, semantic_tag::code, *this, ec);
370
+ break;
371
+ }
372
+ case jsoncons::bson::bson_type::regex_type:
373
+ {
374
+ text_buffer_.clear();
375
+ text_buffer_.push_back('/');
376
+ read_cstring(ec);
377
+ if (ec)
378
+ {
379
+ return;
380
+ }
381
+ text_buffer_.push_back('/');
382
+ read_cstring(ec);
383
+ if (ec)
384
+ {
385
+ return;
386
+ }
387
+ more_ = visitor.string_value(text_buffer_, semantic_tag::regex, *this, ec);
388
+ break;
389
+ }
390
+ case jsoncons::bson::bson_type::document_type:
391
+ {
392
+ begin_document(visitor,ec);
393
+ break;
394
+ }
395
+
396
+ case jsoncons::bson::bson_type::array_type:
397
+ {
398
+ begin_array(visitor,ec);
399
+ break;
400
+ }
401
+ case jsoncons::bson::bson_type::undefined_type:
402
+ {
403
+ more_ = visitor.null_value(semantic_tag::undefined, *this, ec);
404
+ break;
405
+ }
406
+ case jsoncons::bson::bson_type::null_type:
407
+ {
408
+ more_ = visitor.null_value(semantic_tag::none, *this, ec);
409
+ break;
410
+ }
411
+ case jsoncons::bson::bson_type::bool_type:
412
+ {
413
+ uint8_t c;
414
+ std::size_t n = source_.read(&c, 1);
415
+ state_stack_.back().pos += n;
416
+ if (JSONCONS_UNLIKELY(n != 1))
417
+ {
418
+ ec = bson_errc::unexpected_eof;
419
+ more_ = false;
420
+ return;
421
+ }
422
+ more_ = visitor.bool_value(c != 0, semantic_tag::none, *this, ec);
423
+ break;
424
+ }
425
+ case jsoncons::bson::bson_type::int32_type:
426
+ {
427
+ uint8_t buf[sizeof(int32_t)];
428
+ std::size_t n = source_.read(buf, sizeof(int32_t));
429
+ state_stack_.back().pos += n;
430
+ if (JSONCONS_UNLIKELY(n != sizeof(int32_t)))
431
+ {
432
+ ec = bson_errc::unexpected_eof;
433
+ more_ = false;
434
+ return;
435
+ }
436
+ auto val = binary::little_to_native<int32_t>(buf, sizeof(buf));
437
+ more_ = visitor.int64_value(val, semantic_tag::none, *this, ec);
438
+ break;
439
+ }
440
+
441
+ case jsoncons::bson::bson_type::timestamp_type:
442
+ {
443
+ uint8_t buf[sizeof(uint64_t)];
444
+ std::size_t n = source_.read(buf, sizeof(uint64_t));
445
+ state_stack_.back().pos += n;
446
+ if (JSONCONS_UNLIKELY(n != sizeof(uint64_t)))
447
+ {
448
+ ec = bson_errc::unexpected_eof;
449
+ more_ = false;
450
+ return;
451
+ }
452
+ auto val = binary::little_to_native<uint64_t>(buf, sizeof(buf));
453
+ more_ = visitor.uint64_value(val, semantic_tag::none, *this, ec);
454
+ break;
455
+ }
456
+
457
+ case jsoncons::bson::bson_type::int64_type:
458
+ {
459
+ uint8_t buf[sizeof(int64_t)];
460
+ std::size_t n = source_.read(buf, sizeof(int64_t));
461
+ state_stack_.back().pos += n;
462
+ if (JSONCONS_UNLIKELY(n != sizeof(int64_t)))
463
+ {
464
+ ec = bson_errc::unexpected_eof;
465
+ more_ = false;
466
+ return;
467
+ }
468
+ auto val = binary::little_to_native<int64_t>(buf, sizeof(buf));
469
+ more_ = visitor.int64_value(val, semantic_tag::none, *this, ec);
470
+ break;
471
+ }
472
+
473
+ case jsoncons::bson::bson_type::datetime_type:
474
+ {
475
+ uint8_t buf[sizeof(int64_t)];
476
+ std::size_t n = source_.read(buf, sizeof(int64_t));
477
+ state_stack_.back().pos += n;
478
+ if (JSONCONS_UNLIKELY(n != sizeof(int64_t)))
479
+ {
480
+ ec = bson_errc::unexpected_eof;
481
+ more_ = false;
482
+ return;
483
+ }
484
+ auto val = binary::little_to_native<int64_t>(buf, sizeof(buf));
485
+ more_ = visitor.int64_value(val, semantic_tag::epoch_milli, *this, ec);
486
+ break;
487
+ }
488
+ case jsoncons::bson::bson_type::binary_type:
489
+ {
490
+ uint8_t buf[sizeof(int32_t)];
491
+ std::size_t n = source_.read(buf, sizeof(int32_t));
492
+ state_stack_.back().pos += n;
493
+ if (JSONCONS_UNLIKELY(n != sizeof(int32_t)))
494
+ {
495
+ ec = bson_errc::unexpected_eof;
496
+ more_ = false;
497
+ return;
498
+ }
499
+ const auto len = binary::little_to_native<int32_t>(buf, sizeof(buf));
500
+ if (JSONCONS_UNLIKELY(len < 0))
501
+ {
502
+ ec = bson_errc::length_is_negative;
503
+ more_ = false;
504
+ return;
505
+ }
506
+ uint8_t subtype;
507
+ n = source_.read(&subtype, 1);
508
+ state_stack_.back().pos += n;
509
+ if (JSONCONS_UNLIKELY(n != 1))
510
+ {
511
+ ec = bson_errc::unexpected_eof;
512
+ more_ = false;
513
+ return;
514
+ }
515
+
516
+ bytes_buffer_.clear();
517
+ n = source_reader<Source>::read(source_, bytes_buffer_, len);
518
+ state_stack_.back().pos += n;
519
+ if (JSONCONS_UNLIKELY(n != static_cast<std::size_t>(len)))
520
+ {
521
+ ec = bson_errc::unexpected_eof;
522
+ more_ = false;
523
+ return;
524
+ }
525
+
526
+ more_ = visitor.byte_string_value(bytes_buffer_,
527
+ subtype,
528
+ *this,
529
+ ec);
530
+ break;
531
+ }
532
+ case jsoncons::bson::bson_type::decimal128_type:
533
+ {
534
+ uint8_t buf[sizeof(uint64_t)*2];
535
+ std::size_t n = source_.read(buf, sizeof(buf));
536
+ state_stack_.back().pos += n;
537
+ if (JSONCONS_UNLIKELY(n != sizeof(buf)))
538
+ {
539
+ ec = bson_errc::unexpected_eof;
540
+ more_ = false;
541
+ return;
542
+ }
543
+
544
+ decimal128_t dec;
545
+ dec.low = binary::little_to_native<uint64_t>(buf, sizeof(uint64_t));
546
+ dec.high = binary::little_to_native<uint64_t>(buf+sizeof(uint64_t), sizeof(uint64_t));
547
+
548
+ text_buffer_.clear();
549
+ text_buffer_.resize(bson::decimal128_limits::buf_size);
550
+ auto r = bson::decimal128_to_chars(&text_buffer_[0], &text_buffer_[0]+text_buffer_.size(), dec);
551
+ more_ = visitor.string_value(string_view(text_buffer_.data(),static_cast<std::size_t>(r.ptr-text_buffer_.data())), semantic_tag::float128, *this, ec);
552
+ break;
553
+ }
554
+ case jsoncons::bson::bson_type::object_id_type:
555
+ {
556
+ uint8_t buf[12];
557
+ std::size_t n = source_.read(buf, sizeof(buf));
558
+ state_stack_.back().pos += n;
559
+ if (JSONCONS_UNLIKELY(n != sizeof(buf)))
560
+ {
561
+ ec = bson_errc::unexpected_eof;
562
+ more_ = false;
563
+ return;
564
+ }
565
+
566
+ oid_t oid(buf);
567
+ to_string(oid, text_buffer_);
568
+
569
+ more_ = visitor.string_value(text_buffer_, semantic_tag::id, *this, ec);
570
+ break;
571
+ }
572
+ default:
573
+ {
574
+ ec = bson_errc::unknown_type;
575
+ more_ = false;
576
+ return;
577
+ }
578
+ }
579
+ }
580
+
581
+ void read_cstring(std::error_code& ec)
582
+ {
583
+ uint8_t c = 0xff;
584
+ while (true)
585
+ {
586
+ std::size_t n = source_.read(&c, 1);
587
+ state_stack_.back().pos += n;
588
+ if (JSONCONS_UNLIKELY(n != 1))
589
+ {
590
+ ec = bson_errc::unexpected_eof;
591
+ more_ = false;
592
+ return;
593
+ }
594
+ if (c == 0)
595
+ {
596
+ break;
597
+ }
598
+ text_buffer_.push_back(c);
599
+ }
600
+ }
601
+
602
+ void read_string(std::error_code& ec)
603
+ {
604
+ uint8_t buf[sizeof(int32_t)];
605
+ std::size_t n = source_.read(buf, sizeof(int32_t));
606
+ state_stack_.back().pos += n;
607
+ if (JSONCONS_UNLIKELY(n != sizeof(int32_t)))
608
+ {
609
+ ec = bson_errc::unexpected_eof;
610
+ more_ = false;
611
+ return;
612
+ }
613
+ auto len = binary::little_to_native<int32_t>(buf, sizeof(buf));
614
+ if (JSONCONS_UNLIKELY(len < 1))
615
+ {
616
+ ec = bson_errc::string_length_is_non_positive;
617
+ more_ = false;
618
+ return;
619
+ }
620
+
621
+ std::size_t size = static_cast<std::size_t>(len) - static_cast<std::size_t>(1);
622
+ n = source_reader<Source>::read(source_, text_buffer_, size);
623
+ state_stack_.back().pos += n;
624
+
625
+ if (JSONCONS_UNLIKELY(n != size))
626
+ {
627
+ ec = bson_errc::unexpected_eof;
628
+ more_ = false;
629
+ return;
630
+ }
631
+ uint8_t c;
632
+ n = source_.read(&c, 1);
633
+ state_stack_.back().pos += n;
634
+ if (JSONCONS_UNLIKELY(n != 1))
635
+ {
636
+ ec = bson_errc::unexpected_eof;
637
+ more_ = false;
638
+ return;
639
+ }
640
+ }
641
+ };
642
+
643
+ }}
644
+
645
+ #endif