jsoncons 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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,502 @@
1
+ // Copyright 2018 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_UBJSON_UBJSON_ENCODER_HPP
8
+ #define JSONCONS_UBJSON_UBJSON_ENCODER_HPP
9
+
10
+ #include <string>
11
+ #include <vector>
12
+ #include <limits> // std::numeric_limits
13
+ #include <memory>
14
+ #include <utility> // std::move
15
+ #include <jsoncons/json_exception.hpp>
16
+ #include <jsoncons/json_visitor.hpp>
17
+ #include <jsoncons/config/jsoncons_config.hpp>
18
+ #include <jsoncons/sink.hpp>
19
+ #include <jsoncons/detail/parse_number.hpp>
20
+ #include <jsoncons_ext/ubjson/ubjson_type.hpp>
21
+ #include <jsoncons_ext/ubjson/ubjson_error.hpp>
22
+ #include <jsoncons_ext/ubjson/ubjson_options.hpp>
23
+
24
+ namespace jsoncons { namespace ubjson {
25
+
26
+ enum class ubjson_container_type {object, indefinite_length_object, array, indefinite_length_array};
27
+
28
+ template<class Sink=jsoncons::binary_stream_sink,class Allocator=std::allocator<char>>
29
+ class basic_ubjson_encoder final : public basic_json_visitor<char>
30
+ {
31
+
32
+ enum class decimal_parse_state { start, integer, exp1, exp2, fraction1 };
33
+ public:
34
+ using allocator_type = Allocator;
35
+ using typename basic_json_visitor<char>::string_view_type;
36
+ using sink_type = Sink;
37
+
38
+ private:
39
+ struct stack_item
40
+ {
41
+ ubjson_container_type type_;
42
+ std::size_t length_;
43
+ std::size_t count_;
44
+
45
+ stack_item(ubjson_container_type type, std::size_t length = 0) noexcept
46
+ : type_(type), length_(length), count_(0)
47
+ {
48
+ }
49
+
50
+ std::size_t length() const
51
+ {
52
+ return length_;
53
+ }
54
+
55
+ std::size_t count() const
56
+ {
57
+ return count_;
58
+ }
59
+
60
+ bool is_object() const
61
+ {
62
+ return type_ == ubjson_container_type::object || type_ == ubjson_container_type::indefinite_length_object;
63
+ }
64
+
65
+ bool is_indefinite_length() const
66
+ {
67
+ return type_ == ubjson_container_type::indefinite_length_array || type_ == ubjson_container_type::indefinite_length_object;
68
+ }
69
+
70
+ };
71
+
72
+ Sink sink_;
73
+ const ubjson_encode_options options_;
74
+ allocator_type alloc_;
75
+
76
+ std::vector<stack_item> stack_;
77
+ int nesting_depth_;
78
+
79
+ // Noncopyable and nonmoveable
80
+ basic_ubjson_encoder(const basic_ubjson_encoder&) = delete;
81
+ basic_ubjson_encoder& operator=(const basic_ubjson_encoder&) = delete;
82
+ public:
83
+ basic_ubjson_encoder(Sink&& sink,
84
+ const Allocator& alloc = Allocator())
85
+ : basic_ubjson_encoder(std::forward<Sink>(sink), ubjson_encode_options(), alloc)
86
+ {
87
+ }
88
+
89
+ explicit basic_ubjson_encoder(Sink&& sink,
90
+ const ubjson_encode_options& options,
91
+ const Allocator& alloc = Allocator())
92
+ : sink_(std::forward<Sink>(sink)),
93
+ options_(options),
94
+ alloc_(alloc),
95
+ nesting_depth_(0)
96
+ {
97
+ }
98
+
99
+ void reset()
100
+ {
101
+ stack_.clear();
102
+ nesting_depth_ = 0;
103
+ }
104
+
105
+ void reset(Sink&& sink)
106
+ {
107
+ sink_ = std::move(sink);
108
+ reset();
109
+ }
110
+
111
+ ~basic_ubjson_encoder() noexcept
112
+ {
113
+ JSONCONS_TRY
114
+ {
115
+ sink_.flush();
116
+ }
117
+ JSONCONS_CATCH(...)
118
+ {
119
+ }
120
+ }
121
+
122
+ private:
123
+ // Implementing methods
124
+
125
+ void visit_flush() override
126
+ {
127
+ sink_.flush();
128
+ }
129
+
130
+ bool visit_begin_object(semantic_tag, const ser_context&, std::error_code& ec) override
131
+ {
132
+ if (JSONCONS_UNLIKELY(++nesting_depth_ > options_.max_nesting_depth()))
133
+ {
134
+ ec = ubjson_errc::max_nesting_depth_exceeded;
135
+ return false;
136
+ }
137
+ stack_.emplace_back(ubjson_container_type::indefinite_length_object);
138
+ sink_.push_back(jsoncons::ubjson::ubjson_type::start_object_marker);
139
+
140
+ return true;
141
+ }
142
+
143
+ bool visit_begin_object(std::size_t length, semantic_tag, const ser_context&, std::error_code& ec) override
144
+ {
145
+ if (JSONCONS_UNLIKELY(++nesting_depth_ > options_.max_nesting_depth()))
146
+ {
147
+ ec = ubjson_errc::max_nesting_depth_exceeded;
148
+ return false;
149
+ }
150
+ stack_.emplace_back(ubjson_container_type::object, length);
151
+ sink_.push_back(jsoncons::ubjson::ubjson_type::start_object_marker);
152
+ sink_.push_back(jsoncons::ubjson::ubjson_type::count_marker);
153
+ put_length(length);
154
+
155
+ return true;
156
+ }
157
+
158
+ bool visit_end_object(const ser_context&, std::error_code& ec) override
159
+ {
160
+ JSONCONS_ASSERT(!stack_.empty());
161
+ --nesting_depth_;
162
+
163
+ if (stack_.back().is_indefinite_length())
164
+ {
165
+ sink_.push_back(jsoncons::ubjson::ubjson_type::end_object_marker);
166
+ }
167
+ else
168
+ {
169
+ if (stack_.back().count() < stack_.back().length())
170
+ {
171
+ ec = ubjson_errc::too_few_items;
172
+ return false;
173
+ }
174
+ if (stack_.back().count() > stack_.back().length())
175
+ {
176
+ ec = ubjson_errc::too_many_items;
177
+ return false;
178
+ }
179
+ }
180
+ stack_.pop_back();
181
+ end_value();
182
+ return true;
183
+ }
184
+
185
+ bool visit_begin_array(semantic_tag, const ser_context&, std::error_code& ec) override
186
+ {
187
+ if (JSONCONS_UNLIKELY(++nesting_depth_ > options_.max_nesting_depth()))
188
+ {
189
+ ec = ubjson_errc::max_nesting_depth_exceeded;
190
+ return false;
191
+ }
192
+ stack_.emplace_back(ubjson_container_type::indefinite_length_array);
193
+ sink_.push_back(jsoncons::ubjson::ubjson_type::start_array_marker);
194
+
195
+ return true;
196
+ }
197
+
198
+ bool visit_begin_array(std::size_t length, semantic_tag, const ser_context&, std::error_code& ec) override
199
+ {
200
+ if (JSONCONS_UNLIKELY(++nesting_depth_ > options_.max_nesting_depth()))
201
+ {
202
+ ec = ubjson_errc::max_nesting_depth_exceeded;
203
+ return false;
204
+ }
205
+ stack_.emplace_back(ubjson_container_type::array, length);
206
+ sink_.push_back(jsoncons::ubjson::ubjson_type::start_array_marker);
207
+ sink_.push_back(jsoncons::ubjson::ubjson_type::count_marker);
208
+ put_length(length);
209
+
210
+ return true;
211
+ }
212
+
213
+ bool visit_end_array(const ser_context&, std::error_code& ec) override
214
+ {
215
+ JSONCONS_ASSERT(!stack_.empty());
216
+ --nesting_depth_;
217
+
218
+ if (stack_.back().is_indefinite_length())
219
+ {
220
+ sink_.push_back(jsoncons::ubjson::ubjson_type::end_array_marker);
221
+ }
222
+ else
223
+ {
224
+ if (stack_.back().count() < stack_.back().length())
225
+ {
226
+ ec = ubjson_errc::too_few_items;
227
+ return false;
228
+ }
229
+ if (stack_.back().count() > stack_.back().length())
230
+ {
231
+ ec = ubjson_errc::too_many_items;
232
+ return false;
233
+ }
234
+ }
235
+ stack_.pop_back();
236
+ end_value();
237
+ return true;
238
+ }
239
+
240
+ bool visit_key(const string_view_type& name, const ser_context&, std::error_code& ec) override
241
+ {
242
+ auto sink = unicode_traits::validate(name.data(), name.size());
243
+ if (sink.ec != unicode_traits::conv_errc())
244
+ {
245
+ ec = ubjson_errc::invalid_utf8_text_string;
246
+ return false;
247
+ }
248
+
249
+ put_length(name.length());
250
+
251
+ for (auto c : name)
252
+ {
253
+ sink_.push_back(c);
254
+ }
255
+ return true;
256
+ }
257
+
258
+ bool visit_null(semantic_tag, const ser_context&, std::error_code&) override
259
+ {
260
+ // nil
261
+ binary::native_to_big(static_cast<uint8_t>(jsoncons::ubjson::ubjson_type::null_type), std::back_inserter(sink_));
262
+ end_value();
263
+ return true;
264
+ }
265
+
266
+ bool visit_string(const string_view_type& sv, semantic_tag tag, const ser_context&, std::error_code& ec) override
267
+ {
268
+ switch (tag)
269
+ {
270
+ case semantic_tag::bigint:
271
+ case semantic_tag::bigdec:
272
+ {
273
+ sink_.push_back(jsoncons::ubjson::ubjson_type::high_precision_number_type);
274
+ break;
275
+ }
276
+ default:
277
+ {
278
+ sink_.push_back(jsoncons::ubjson::ubjson_type::string_type);
279
+ break;
280
+ }
281
+ }
282
+
283
+ auto sink = unicode_traits::validate(sv.data(), sv.size());
284
+ if (sink.ec != unicode_traits::conv_errc())
285
+ {
286
+ ec = ubjson_errc::invalid_utf8_text_string;
287
+ return false;
288
+ }
289
+
290
+ put_length(sv.length());
291
+
292
+ for (auto c : sv)
293
+ {
294
+ sink_.push_back(c);
295
+ }
296
+
297
+ end_value();
298
+ return true;
299
+ }
300
+
301
+ void put_length(std::size_t length)
302
+ {
303
+ if (length <= (std::numeric_limits<uint8_t>::max)())
304
+ {
305
+ sink_.push_back(ubjson_type::uint8_type);
306
+ binary::native_to_big(static_cast<uint8_t>(length), std::back_inserter(sink_));
307
+ }
308
+ else if (length <= (std::size_t)(std::numeric_limits<int16_t>::max)())
309
+ {
310
+ sink_.push_back(ubjson_type::int16_type);
311
+ binary::native_to_big(static_cast<uint16_t>(length), std::back_inserter(sink_));
312
+ }
313
+ else if (length <= (std::size_t)(std::numeric_limits<int32_t>::max)())
314
+ {
315
+ sink_.push_back(ubjson_type::int32_type);
316
+ binary::native_to_big(static_cast<uint32_t>(length),std::back_inserter(sink_));
317
+ }
318
+ else if (length <= (std::size_t)(std::numeric_limits<int64_t>::max)())
319
+ {
320
+ sink_.push_back(ubjson_type::int64_type);
321
+ binary::native_to_big(static_cast<uint64_t>(length),std::back_inserter(sink_));
322
+ }
323
+ else
324
+ {
325
+ JSONCONS_THROW(ser_error(ubjson_errc::too_many_items));
326
+ }
327
+ }
328
+
329
+ bool visit_byte_string(const byte_string_view& b,
330
+ semantic_tag,
331
+ const ser_context&,
332
+ std::error_code&) override
333
+ {
334
+
335
+ const size_t length = b.size();
336
+ sink_.push_back(jsoncons::ubjson::ubjson_type::start_array_marker);
337
+ binary::native_to_big(static_cast<uint8_t>(jsoncons::ubjson::ubjson_type::type_marker), std::back_inserter(sink_));
338
+ binary::native_to_big(static_cast<uint8_t>(jsoncons::ubjson::ubjson_type::uint8_type), std::back_inserter(sink_));
339
+ put_length(length);
340
+
341
+ for (auto c : b)
342
+ {
343
+ sink_.push_back(c);
344
+ }
345
+
346
+ end_value();
347
+ return true;
348
+ }
349
+
350
+ bool visit_double(double val,
351
+ semantic_tag,
352
+ const ser_context&,
353
+ std::error_code&) override
354
+ {
355
+ float valf = (float)val;
356
+ if ((double)valf == val)
357
+ {
358
+ // float 32
359
+ sink_.push_back(static_cast<uint8_t>(jsoncons::ubjson::ubjson_type::float32_type));
360
+ binary::native_to_big(valf,std::back_inserter(sink_));
361
+ }
362
+ else
363
+ {
364
+ // float 64
365
+ sink_.push_back(static_cast<uint8_t>(jsoncons::ubjson::ubjson_type::float64_type));
366
+ binary::native_to_big(val,std::back_inserter(sink_));
367
+ }
368
+
369
+ // write double
370
+
371
+ end_value();
372
+ return true;
373
+ }
374
+
375
+ bool visit_int64(int64_t val,
376
+ semantic_tag,
377
+ const ser_context&,
378
+ std::error_code&) override
379
+ {
380
+ if (val >= 0)
381
+ {
382
+ if (val <= (std::numeric_limits<uint8_t>::max)())
383
+ {
384
+ // uint 8 stores a 8-bit unsigned integer
385
+ sink_.push_back(jsoncons::ubjson::ubjson_type::uint8_type);
386
+ binary::native_to_big(static_cast<uint8_t>(val),std::back_inserter(sink_));
387
+ }
388
+ else if (val <= (std::numeric_limits<int16_t>::max)())
389
+ {
390
+ // uint 16 stores a 16-bit big-endian unsigned integer
391
+ sink_.push_back(jsoncons::ubjson::ubjson_type::int16_type);
392
+ binary::native_to_big(static_cast<int16_t>(val),std::back_inserter(sink_));
393
+ }
394
+ else if (val <= (std::numeric_limits<int32_t>::max)())
395
+ {
396
+ // uint 32 stores a 32-bit big-endian unsigned integer
397
+ sink_.push_back(jsoncons::ubjson::ubjson_type::int32_type);
398
+ binary::native_to_big(static_cast<int32_t>(val),std::back_inserter(sink_));
399
+ }
400
+ else if (val <= (std::numeric_limits<int64_t>::max)())
401
+ {
402
+ // int 64 stores a 64-bit big-endian signed integer
403
+ sink_.push_back(jsoncons::ubjson::ubjson_type::int64_type);
404
+ binary::native_to_big(static_cast<int64_t>(val),std::back_inserter(sink_));
405
+ }
406
+ else
407
+ {
408
+ // big integer
409
+ }
410
+ }
411
+ else
412
+ {
413
+ if (val >= (std::numeric_limits<int8_t>::lowest)())
414
+ {
415
+ // int 8 stores a 8-bit signed integer
416
+ sink_.push_back(jsoncons::ubjson::ubjson_type::int8_type);
417
+ binary::native_to_big(static_cast<int8_t>(val),std::back_inserter(sink_));
418
+ }
419
+ else if (val >= (std::numeric_limits<int16_t>::lowest)())
420
+ {
421
+ // int 16 stores a 16-bit big-endian signed integer
422
+ sink_.push_back(jsoncons::ubjson::ubjson_type::int16_type);
423
+ binary::native_to_big(static_cast<int16_t>(val),std::back_inserter(sink_));
424
+ }
425
+ else if (val >= (std::numeric_limits<int32_t>::lowest)())
426
+ {
427
+ // int 32 stores a 32-bit big-endian signed integer
428
+ sink_.push_back(jsoncons::ubjson::ubjson_type::int32_type);
429
+ binary::native_to_big(static_cast<int32_t>(val),std::back_inserter(sink_));
430
+ }
431
+ else if (val >= (std::numeric_limits<int64_t>::lowest)())
432
+ {
433
+ // int 64 stores a 64-bit big-endian signed integer
434
+ sink_.push_back(jsoncons::ubjson::ubjson_type::int64_type);
435
+ binary::native_to_big(static_cast<int64_t>(val),std::back_inserter(sink_));
436
+ }
437
+ }
438
+ end_value();
439
+ return true;
440
+ }
441
+
442
+ bool visit_uint64(uint64_t val,
443
+ semantic_tag,
444
+ const ser_context&,
445
+ std::error_code&) override
446
+ {
447
+ if (val <= (std::numeric_limits<uint8_t>::max)())
448
+ {
449
+ sink_.push_back(jsoncons::ubjson::ubjson_type::uint8_type);
450
+ binary::native_to_big(static_cast<uint8_t>(val),std::back_inserter(sink_));
451
+ }
452
+ else if (val <= static_cast<uint64_t>((std::numeric_limits<int16_t>::max)()))
453
+ {
454
+ sink_.push_back(jsoncons::ubjson::ubjson_type::int16_type);
455
+ binary::native_to_big(static_cast<int16_t>(val),std::back_inserter(sink_));
456
+ }
457
+ else if (val <= static_cast<uint64_t>((std::numeric_limits<int32_t>::max)()))
458
+ {
459
+ sink_.push_back(jsoncons::ubjson::ubjson_type::int32_type);
460
+ binary::native_to_big(static_cast<int32_t>(val),std::back_inserter(sink_));
461
+ }
462
+ else if (val <= static_cast<uint64_t>((std::numeric_limits<int64_t>::max)()))
463
+ {
464
+ sink_.push_back(jsoncons::ubjson::ubjson_type::int64_type);
465
+ binary::native_to_big(static_cast<int64_t>(val),std::back_inserter(sink_));
466
+ }
467
+ end_value();
468
+ return true;
469
+ }
470
+
471
+ bool visit_bool(bool val, semantic_tag, const ser_context&, std::error_code&) override
472
+ {
473
+ // true and false
474
+ sink_.push_back(static_cast<uint8_t>(val ? jsoncons::ubjson::ubjson_type::true_type : jsoncons::ubjson::ubjson_type::false_type));
475
+
476
+ end_value();
477
+ return true;
478
+ }
479
+
480
+ void end_value()
481
+ {
482
+ if (!stack_.empty())
483
+ {
484
+ ++stack_.back().count_;
485
+ }
486
+ }
487
+ };
488
+
489
+ using ubjson_stream_encoder = basic_ubjson_encoder<jsoncons::binary_stream_sink>;
490
+ using ubjson_bytes_encoder = basic_ubjson_encoder<jsoncons::bytes_sink<std::vector<uint8_t>>>;
491
+
492
+ #if !defined(JSONCONS_NO_DEPRECATED)
493
+ template<class Sink=jsoncons::binary_stream_sink>
494
+ using basic_ubjson_serializer = basic_ubjson_encoder<Sink>;
495
+
496
+ JSONCONS_DEPRECATED_MSG("Instead, use ubjson_stream_encoder") typedef ubjson_stream_encoder ubjson_encoder;
497
+ JSONCONS_DEPRECATED_MSG("Instead, use ubjson_stream_encoder") typedef ubjson_stream_encoder ubjson_serializer;
498
+ JSONCONS_DEPRECATED_MSG("Instead, use ubjson_bytes_encoder") typedef ubjson_bytes_encoder ubjson_buffer_serializer;
499
+ #endif
500
+
501
+ }}
502
+ #endif
@@ -0,0 +1,100 @@
1
+ /// Copyright 2018 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_UBJSON_UBJSON_ERROR_HPP
8
+ #define JSONCONS_UBJSON_UBJSON_ERROR_HPP
9
+
10
+ #include <system_error>
11
+ #include <jsoncons/config/jsoncons_config.hpp>
12
+
13
+ namespace jsoncons { namespace ubjson {
14
+
15
+ enum class ubjson_errc
16
+ {
17
+ success = 0,
18
+ unexpected_eof = 1,
19
+ source_error,
20
+ count_required_after_type,
21
+ length_is_negative,
22
+ length_must_be_integer,
23
+ unknown_type,
24
+ invalid_utf8_text_string,
25
+ too_many_items,
26
+ too_few_items,
27
+ number_too_large,
28
+ max_nesting_depth_exceeded,
29
+ key_expected,
30
+ max_items_exceeded
31
+ };
32
+
33
+ class ubjson_error_category_impl
34
+ : public std::error_category
35
+ {
36
+ public:
37
+ const char* name() const noexcept override
38
+ {
39
+ return "jsoncons/ubjson";
40
+ }
41
+ std::string message(int ev) const override
42
+ {
43
+ switch (static_cast<ubjson_errc>(ev))
44
+ {
45
+ case ubjson_errc::unexpected_eof:
46
+ return "Unexpected end of file";
47
+ case ubjson_errc::source_error:
48
+ return "Source error";
49
+ case ubjson_errc::count_required_after_type:
50
+ return "Type is specified for container, but count is not specified";
51
+ case ubjson_errc::length_is_negative:
52
+ return "Request for the length of an array, map or string returned a negative result";
53
+ case ubjson_errc::length_must_be_integer:
54
+ return "Length must be a integer numeric type (int8, uint8, int16, int32, int64)";
55
+ case ubjson_errc::unknown_type:
56
+ return "Unknown type";
57
+ case ubjson_errc::invalid_utf8_text_string:
58
+ return "Illegal UTF-8 encoding in text string";
59
+ case ubjson_errc::too_many_items:
60
+ return "Too many items were added to a UBJSON object or array of known length";
61
+ case ubjson_errc::too_few_items:
62
+ return "Too few items were added to a UBJSON object or array of known length";
63
+ case ubjson_errc::number_too_large:
64
+ return "Number exceeds implementation limits";
65
+ case ubjson_errc::max_nesting_depth_exceeded:
66
+ return "Data item nesting exceeds limit in options";
67
+ case ubjson_errc::key_expected:
68
+ return "Text string key in a map expected";
69
+ case ubjson_errc::max_items_exceeded:
70
+ return "Number of items in UBJSON object or array exceeds limit set in options";
71
+ default:
72
+ return "Unknown UBJSON parser error";
73
+ }
74
+ }
75
+ };
76
+
77
+ inline
78
+ const std::error_category& ubjson_error_category()
79
+ {
80
+ static ubjson_error_category_impl instance;
81
+ return instance;
82
+ }
83
+
84
+ inline
85
+ std::error_code make_error_code(ubjson_errc e)
86
+ {
87
+ return std::error_code(static_cast<int>(e),ubjson_error_category());
88
+ }
89
+
90
+
91
+ }}
92
+
93
+ namespace std {
94
+ template<>
95
+ struct is_error_code_enum<jsoncons::ubjson::ubjson_errc> : public true_type
96
+ {
97
+ };
98
+ }
99
+
100
+ #endif
@@ -0,0 +1,87 @@
1
+ // Copyright 2019 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_UBJSON_UBJSON_OPTIONS_HPP
8
+ #define JSONCONS_UBJSON_UBJSON_OPTIONS_HPP
9
+
10
+ #include <string>
11
+ #include <limits> // std::numeric_limits
12
+ #include <cwchar>
13
+ #include <jsoncons/json_exception.hpp>
14
+
15
+ namespace jsoncons { namespace ubjson {
16
+
17
+ class ubjson_options;
18
+
19
+ class ubjson_options_common
20
+ {
21
+ friend class ubjson_options;
22
+
23
+ int max_nesting_depth_;
24
+ protected:
25
+ virtual ~ubjson_options_common() = default;
26
+
27
+ ubjson_options_common()
28
+ : max_nesting_depth_(1024)
29
+ {
30
+ }
31
+
32
+ ubjson_options_common(const ubjson_options_common&) = default;
33
+ ubjson_options_common& operator=(const ubjson_options_common&) = default;
34
+ ubjson_options_common(ubjson_options_common&&) = default;
35
+ ubjson_options_common& operator=(ubjson_options_common&&) = default;
36
+ public:
37
+ int max_nesting_depth() const
38
+ {
39
+ return max_nesting_depth_;
40
+ }
41
+ };
42
+
43
+ class ubjson_decode_options : public virtual ubjson_options_common
44
+ {
45
+ friend class ubjson_options;
46
+ std::size_t max_items_;
47
+ public:
48
+ ubjson_decode_options() :
49
+ max_items_(1 << 24)
50
+ {
51
+ }
52
+
53
+ std::size_t max_items() const
54
+ {
55
+ return max_items_;
56
+ }
57
+ };
58
+
59
+ class ubjson_encode_options : public virtual ubjson_options_common
60
+ {
61
+ friend class ubjson_options;
62
+ public:
63
+ ubjson_encode_options()
64
+ {
65
+ }
66
+ };
67
+
68
+ class ubjson_options final : public ubjson_decode_options, public ubjson_encode_options
69
+ {
70
+ public:
71
+ using ubjson_options_common::max_nesting_depth;
72
+
73
+ ubjson_options& max_nesting_depth(int value)
74
+ {
75
+ this->max_nesting_depth_ = value;
76
+ return *this;
77
+ }
78
+
79
+ ubjson_options& max_items(std::size_t value)
80
+ {
81
+ this->max_items_ = value;
82
+ return *this;
83
+ }
84
+ };
85
+
86
+ }}
87
+ #endif