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,1766 @@
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_CBOR_CBOR_ENCODER_HPP
8
+ #define JSONCONS_CBOR_CBOR_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> // jsoncons::ser_error
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/cbor/cbor_error.hpp>
21
+ #include <jsoncons_ext/cbor/cbor_options.hpp>
22
+
23
+ namespace jsoncons { namespace cbor {
24
+
25
+ enum class cbor_container_type {object, indefinite_length_object, array, indefinite_length_array};
26
+
27
+ template<class Sink=jsoncons::binary_stream_sink,class Allocator=std::allocator<char>>
28
+ class basic_cbor_encoder final : public basic_json_visitor<char>
29
+ {
30
+ using super_type = basic_json_visitor<char>;
31
+
32
+ enum class decimal_parse_state { start, integer, exp1, exp2, fraction1 };
33
+ enum class hexfloat_parse_state { start, expect_0, expect_x, integer, exp1, exp2, fraction1 };
34
+
35
+ static constexpr int64_t nanos_in_second = 1000000000;
36
+ static constexpr int64_t millis_in_second = 1000;
37
+
38
+ public:
39
+ using allocator_type = Allocator;
40
+ using sink_type = Sink;
41
+ using typename super_type::char_type;
42
+ using typename super_type::string_view_type;
43
+
44
+ private:
45
+ using char_allocator_type = typename std::allocator_traits<allocator_type>:: template rebind_alloc<char_type>;
46
+ using byte_allocator_type = typename std::allocator_traits<allocator_type>:: template rebind_alloc<uint8_t>;
47
+
48
+ using string_type = std::basic_string<char_type,std::char_traits<char_type>,char_allocator_type>;
49
+ using byte_string_type = basic_byte_string<byte_allocator_type>;
50
+
51
+ struct stack_item
52
+ {
53
+ cbor_container_type type_;
54
+ std::size_t length_;
55
+ std::size_t count_;
56
+
57
+ stack_item(cbor_container_type type, std::size_t length = 0) noexcept
58
+ : type_(type), length_(length), count_(0)
59
+ {
60
+ }
61
+
62
+ std::size_t length() const
63
+ {
64
+ return length_;
65
+ }
66
+
67
+ std::size_t count() const
68
+ {
69
+ return count_;
70
+ }
71
+
72
+ bool is_object() const
73
+ {
74
+ return type_ == cbor_container_type::object || type_ == cbor_container_type::indefinite_length_object;
75
+ }
76
+
77
+ bool is_indefinite_length() const
78
+ {
79
+ return type_ == cbor_container_type::indefinite_length_array || type_ == cbor_container_type::indefinite_length_object;
80
+ }
81
+
82
+ };
83
+
84
+ typedef typename std::allocator_traits<allocator_type>:: template rebind_alloc<std::pair<const string_type,size_t>> string_size_allocator_type;
85
+ typedef typename std::allocator_traits<allocator_type>:: template rebind_alloc<std::pair<const byte_string_type,size_t>> byte_string_size_allocator_type;
86
+ typedef typename std::allocator_traits<allocator_type>:: template rebind_alloc<stack_item> stack_item_allocator_type;
87
+
88
+ Sink sink_;
89
+ const cbor_encode_options options_;
90
+ allocator_type alloc_;
91
+
92
+ std::vector<stack_item,stack_item_allocator_type> stack_;
93
+ std::map<string_type,size_t,std::less<string_type>,string_size_allocator_type> stringref_map_;
94
+ std::map<byte_string_type,size_t,std::less<byte_string_type>,byte_string_size_allocator_type> bytestringref_map_;
95
+ std::size_t next_stringref_ = 0;
96
+ int nesting_depth_;
97
+
98
+ // Noncopyable and nonmoveable
99
+ basic_cbor_encoder(const basic_cbor_encoder&) = delete;
100
+ basic_cbor_encoder& operator=(const basic_cbor_encoder&) = delete;
101
+ public:
102
+ explicit basic_cbor_encoder(Sink&& sink,
103
+ const Allocator& alloc = Allocator())
104
+ : basic_cbor_encoder(std::forward<Sink>(sink), cbor_encode_options(), alloc)
105
+ {
106
+ }
107
+ basic_cbor_encoder(Sink&& sink,
108
+ const cbor_encode_options& options,
109
+ const Allocator& alloc = Allocator())
110
+ : sink_(std::forward<Sink>(sink)),
111
+ options_(options),
112
+ alloc_(alloc),
113
+ stack_(alloc),
114
+ #if !defined(JSONCONS_NO_MAP_CONS_TAKES_ALLOCATOR)
115
+ stringref_map_(alloc),
116
+ bytestringref_map_(alloc),
117
+ #endif
118
+ nesting_depth_(0)
119
+ {
120
+ if (options.pack_strings())
121
+ {
122
+ write_tag(256);
123
+ }
124
+ }
125
+
126
+ ~basic_cbor_encoder() noexcept
127
+ {
128
+ JSONCONS_TRY
129
+ {
130
+ sink_.flush();
131
+ }
132
+ JSONCONS_CATCH(...)
133
+ {
134
+ }
135
+ }
136
+
137
+ void reset()
138
+ {
139
+ stack_.clear();
140
+ stringref_map_.clear();
141
+ bytestringref_map_.clear();
142
+ next_stringref_ = 0;
143
+ nesting_depth_ = 0;
144
+ }
145
+
146
+ void reset(Sink&& sink)
147
+ {
148
+ sink_ = std::move(sink);
149
+ reset();
150
+ }
151
+
152
+ private:
153
+ // Implementing methods
154
+
155
+ void visit_flush() override
156
+ {
157
+ sink_.flush();
158
+ }
159
+
160
+ bool visit_begin_object(semantic_tag, const ser_context&, std::error_code& ec) override
161
+ {
162
+ if (JSONCONS_UNLIKELY(++nesting_depth_ > options_.max_nesting_depth()))
163
+ {
164
+ ec = cbor_errc::max_nesting_depth_exceeded;
165
+ return false;
166
+ }
167
+ stack_.emplace_back(cbor_container_type::indefinite_length_object);
168
+
169
+ sink_.push_back(0xbf);
170
+ return true;
171
+ }
172
+
173
+ bool visit_begin_object(std::size_t length, semantic_tag, const ser_context&, std::error_code& ec) override
174
+ {
175
+ if (JSONCONS_UNLIKELY(++nesting_depth_ > options_.max_nesting_depth()))
176
+ {
177
+ ec = cbor_errc::max_nesting_depth_exceeded;
178
+ return false;
179
+ }
180
+ stack_.emplace_back(cbor_container_type::object, length);
181
+
182
+ if (length <= 0x17)
183
+ {
184
+ binary::native_to_big(static_cast<uint8_t>(0xa0 + length),
185
+ std::back_inserter(sink_));
186
+ }
187
+ else if (length <= 0xff)
188
+ {
189
+ binary::native_to_big(static_cast<uint8_t>(0xb8),
190
+ std::back_inserter(sink_));
191
+ binary::native_to_big(static_cast<uint8_t>(length),
192
+ std::back_inserter(sink_));
193
+ }
194
+ else if (length <= 0xffff)
195
+ {
196
+ binary::native_to_big(static_cast<uint8_t>(0xb9),
197
+ std::back_inserter(sink_));
198
+ binary::native_to_big(static_cast<uint16_t>(length),
199
+ std::back_inserter(sink_));
200
+ }
201
+ else if (length <= 0xffffffff)
202
+ {
203
+ binary::native_to_big(static_cast<uint8_t>(0xba),
204
+ std::back_inserter(sink_));
205
+ binary::native_to_big(static_cast<uint32_t>(length),
206
+ std::back_inserter(sink_));
207
+ }
208
+ else if (length <= 0xffffffffffffffff)
209
+ {
210
+ binary::native_to_big(static_cast<uint8_t>(0xbb),
211
+ std::back_inserter(sink_));
212
+ binary::native_to_big(static_cast<uint64_t>(length),
213
+ std::back_inserter(sink_));
214
+ }
215
+
216
+ return true;
217
+ }
218
+
219
+ bool visit_end_object(const ser_context&, std::error_code& ec) override
220
+ {
221
+ JSONCONS_ASSERT(!stack_.empty());
222
+ --nesting_depth_;
223
+
224
+ if (stack_.back().is_indefinite_length())
225
+ {
226
+ sink_.push_back(0xff);
227
+ }
228
+ else
229
+ {
230
+ if (stack_.back().count() < stack_.back().length())
231
+ {
232
+ ec = cbor_errc::too_few_items;
233
+ return false;
234
+ }
235
+ if (stack_.back().count() > stack_.back().length())
236
+ {
237
+ ec = cbor_errc::too_many_items;
238
+ return false;
239
+ }
240
+ }
241
+
242
+ stack_.pop_back();
243
+ end_value();
244
+
245
+ return true;
246
+ }
247
+
248
+ bool visit_begin_array(semantic_tag, const ser_context&, std::error_code& ec) override
249
+ {
250
+ if (JSONCONS_UNLIKELY(++nesting_depth_ > options_.max_nesting_depth()))
251
+ {
252
+ ec = cbor_errc::max_nesting_depth_exceeded;
253
+ return false;
254
+ }
255
+ stack_.emplace_back(cbor_container_type::indefinite_length_array);
256
+ sink_.push_back(0x9f);
257
+ return true;
258
+ }
259
+
260
+ bool visit_begin_array(std::size_t length, semantic_tag, const ser_context&, std::error_code& ec) override
261
+ {
262
+ if (JSONCONS_UNLIKELY(++nesting_depth_ > options_.max_nesting_depth()))
263
+ {
264
+ ec = cbor_errc::max_nesting_depth_exceeded;
265
+ return false;
266
+ }
267
+ stack_.emplace_back(cbor_container_type::array, length);
268
+ if (length <= 0x17)
269
+ {
270
+ binary::native_to_big(static_cast<uint8_t>(0x80 + length),
271
+ std::back_inserter(sink_));
272
+ }
273
+ else if (length <= 0xff)
274
+ {
275
+ binary::native_to_big(static_cast<uint8_t>(0x98),
276
+ std::back_inserter(sink_));
277
+ binary::native_to_big(static_cast<uint8_t>(length),
278
+ std::back_inserter(sink_));
279
+ }
280
+ else if (length <= 0xffff)
281
+ {
282
+ binary::native_to_big(static_cast<uint8_t>(0x99),
283
+ std::back_inserter(sink_));
284
+ binary::native_to_big(static_cast<uint16_t>(length),
285
+ std::back_inserter(sink_));
286
+ }
287
+ else if (length <= 0xffffffff)
288
+ {
289
+ binary::native_to_big(static_cast<uint8_t>(0x9a),
290
+ std::back_inserter(sink_));
291
+ binary::native_to_big(static_cast<uint32_t>(length),
292
+ std::back_inserter(sink_));
293
+ }
294
+ else if (length <= 0xffffffffffffffff)
295
+ {
296
+ binary::native_to_big(static_cast<uint8_t>(0x9b),
297
+ std::back_inserter(sink_));
298
+ binary::native_to_big(static_cast<uint64_t>(length),
299
+ std::back_inserter(sink_));
300
+ }
301
+ return true;
302
+ }
303
+
304
+ bool visit_end_array(const ser_context&, std::error_code& ec) override
305
+ {
306
+ JSONCONS_ASSERT(!stack_.empty());
307
+ --nesting_depth_;
308
+
309
+ if (stack_.back().is_indefinite_length())
310
+ {
311
+ sink_.push_back(0xff);
312
+ }
313
+ else
314
+ {
315
+ if (stack_.back().count() < stack_.back().length())
316
+ {
317
+ ec = cbor_errc::too_few_items;
318
+ return false;
319
+ }
320
+ if (stack_.back().count() > stack_.back().length())
321
+ {
322
+ ec = cbor_errc::too_many_items;
323
+ return false;
324
+ }
325
+ }
326
+
327
+ stack_.pop_back();
328
+ end_value();
329
+
330
+ return true;
331
+ }
332
+
333
+ bool visit_key(const string_view_type& name, const ser_context&, std::error_code&) override
334
+ {
335
+ write_string(name);
336
+ return true;
337
+ }
338
+
339
+ bool visit_null(semantic_tag tag, const ser_context&, std::error_code&) override
340
+ {
341
+ if (tag == semantic_tag::undefined)
342
+ {
343
+ sink_.push_back(0xf7);
344
+ }
345
+ else
346
+ {
347
+ sink_.push_back(0xf6);
348
+ }
349
+
350
+ end_value();
351
+ return true;
352
+ }
353
+
354
+ void write_string(const string_view& sv)
355
+ {
356
+ auto sink = unicode_traits::validate(sv.data(), sv.size());
357
+ if (sink.ec != unicode_traits::conv_errc())
358
+ {
359
+ JSONCONS_THROW(ser_error(cbor_errc::invalid_utf8_text_string));
360
+ }
361
+
362
+ if (options_.pack_strings() && sv.size() >= jsoncons::cbor::detail::min_length_for_stringref(next_stringref_))
363
+ {
364
+ string_type s(sv.data(), sv.size(), alloc_);
365
+ auto it = stringref_map_.find(s);
366
+ if (it == stringref_map_.end())
367
+ {
368
+ stringref_map_.emplace(std::make_pair(std::move(s), next_stringref_++));
369
+ write_utf8_string(sv);
370
+ }
371
+ else
372
+ {
373
+ write_tag(25);
374
+ write_uint64_value(it->second);
375
+ }
376
+ }
377
+ else
378
+ {
379
+ write_utf8_string(sv);
380
+ }
381
+ }
382
+
383
+ void write_utf8_string(const string_view& sv)
384
+ {
385
+ const size_t length = sv.size();
386
+
387
+ if (length <= 0x17)
388
+ {
389
+ // fixstr stores a byte array whose length is upto 31 bytes
390
+ binary::native_to_big(static_cast<uint8_t>(0x60 + length),
391
+ std::back_inserter(sink_));
392
+ }
393
+ else if (length <= 0xff)
394
+ {
395
+ binary::native_to_big(static_cast<uint8_t>(0x78),
396
+ std::back_inserter(sink_));
397
+ binary::native_to_big(static_cast<uint8_t>(length),
398
+ std::back_inserter(sink_));
399
+ }
400
+ else if (length <= 0xffff)
401
+ {
402
+ binary::native_to_big(static_cast<uint8_t>(0x79),
403
+ std::back_inserter(sink_));
404
+ binary::native_to_big(static_cast<uint16_t>(length),
405
+ std::back_inserter(sink_));
406
+ }
407
+ else if (length <= 0xffffffff)
408
+ {
409
+ binary::native_to_big(static_cast<uint8_t>(0x7a),
410
+ std::back_inserter(sink_));
411
+ binary::native_to_big(static_cast<uint32_t>(length),
412
+ std::back_inserter(sink_));
413
+ }
414
+ else if (length <= 0xffffffffffffffff)
415
+ {
416
+ binary::native_to_big(static_cast<uint8_t>(0x7b),
417
+ std::back_inserter(sink_));
418
+ binary::native_to_big(static_cast<uint64_t>(length),
419
+ std::back_inserter(sink_));
420
+ }
421
+
422
+ for (auto c : sv)
423
+ {
424
+ sink_.push_back(c);
425
+ }
426
+ }
427
+
428
+ void write_bignum(bigint& n)
429
+ {
430
+ bool is_neg = n < 0;
431
+ if (is_neg)
432
+ {
433
+ n = - n -1;
434
+ }
435
+
436
+ int signum;
437
+ std::vector<uint8_t> data;
438
+ n.write_bytes_be(signum, data);
439
+ std::size_t length = data.size();
440
+
441
+ if (is_neg)
442
+ {
443
+ write_tag(3);
444
+ }
445
+ else
446
+ {
447
+ write_tag(2);
448
+ }
449
+
450
+ if (length <= 0x17)
451
+ {
452
+ // fixstr stores a byte array whose length is upto 31 bytes
453
+ binary::native_to_big(static_cast<uint8_t>(0x40 + length),
454
+ std::back_inserter(sink_));
455
+ }
456
+ else if (length <= 0xff)
457
+ {
458
+ binary::native_to_big(static_cast<uint8_t>(0x58),
459
+ std::back_inserter(sink_));
460
+ binary::native_to_big(static_cast<uint8_t>(length),
461
+ std::back_inserter(sink_));
462
+ }
463
+ else if (length <= 0xffff)
464
+ {
465
+ binary::native_to_big(static_cast<uint8_t>(0x59),
466
+ std::back_inserter(sink_));
467
+ binary::native_to_big(static_cast<uint16_t>(length),
468
+ std::back_inserter(sink_));
469
+ }
470
+ else if (length <= 0xffffffff)
471
+ {
472
+ binary::native_to_big(static_cast<uint8_t>(0x5a),
473
+ std::back_inserter(sink_));
474
+ binary::native_to_big(static_cast<uint32_t>(length),
475
+ std::back_inserter(sink_));
476
+ }
477
+ else if (length <= 0xffffffffffffffff)
478
+ {
479
+ binary::native_to_big(static_cast<uint8_t>(0x5b),
480
+ std::back_inserter(sink_));
481
+ binary::native_to_big(static_cast<uint64_t>(length),
482
+ std::back_inserter(sink_));
483
+ }
484
+
485
+ for (auto c : data)
486
+ {
487
+ sink_.push_back(c);
488
+ }
489
+ }
490
+
491
+ bool write_decimal_value(const string_view_type& sv, const ser_context& context, std::error_code& ec)
492
+ {
493
+ bool more = true;
494
+
495
+ decimal_parse_state state = decimal_parse_state::start;
496
+ std::basic_string<char> s;
497
+ std::basic_string<char> exponent;
498
+ int64_t scale = 0;
499
+ for (auto c : sv)
500
+ {
501
+ switch (state)
502
+ {
503
+ case decimal_parse_state::start:
504
+ {
505
+ switch (c)
506
+ {
507
+ case '-':
508
+ s.push_back(c);
509
+ state = decimal_parse_state::integer;
510
+ break;
511
+ case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
512
+ s.push_back(c);
513
+ state = decimal_parse_state::integer;
514
+ break;
515
+ default:
516
+ {
517
+ ec = cbor_errc::invalid_decimal_fraction;
518
+ return false;
519
+ }
520
+ }
521
+ break;
522
+ }
523
+ case decimal_parse_state::integer:
524
+ {
525
+ switch (c)
526
+ {
527
+ case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
528
+ s.push_back(c);
529
+ break;
530
+ case 'e': case 'E':
531
+ state = decimal_parse_state::exp1;
532
+ break;
533
+ case '.':
534
+ state = decimal_parse_state::fraction1;
535
+ break;
536
+ default:
537
+ {
538
+ ec = cbor_errc::invalid_decimal_fraction;
539
+ return false;
540
+ }
541
+ }
542
+ break;
543
+ }
544
+ case decimal_parse_state::exp1:
545
+ {
546
+ switch (c)
547
+ {
548
+ case '+':
549
+ state = decimal_parse_state::exp2;
550
+ break;
551
+ case '-':
552
+ exponent.push_back(c);
553
+ state = decimal_parse_state::exp2;
554
+ break;
555
+ case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
556
+ exponent.push_back(c);
557
+ state = decimal_parse_state::exp2;
558
+ break;
559
+ default:
560
+ {
561
+ ec = cbor_errc::invalid_decimal_fraction;
562
+ return false;
563
+ }
564
+ }
565
+ break;
566
+ }
567
+ case decimal_parse_state::exp2:
568
+ {
569
+ switch (c)
570
+ {
571
+ case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
572
+ exponent.push_back(c);
573
+ break;
574
+ default:
575
+ {
576
+ ec = cbor_errc::invalid_decimal_fraction;
577
+ return false;
578
+ }
579
+ }
580
+ break;
581
+ }
582
+ case decimal_parse_state::fraction1:
583
+ {
584
+ switch (c)
585
+ {
586
+ case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':
587
+ s.push_back(c);
588
+ --scale;
589
+ break;
590
+ default:
591
+ {
592
+ ec = cbor_errc::invalid_decimal_fraction;
593
+ return false;
594
+ }
595
+ }
596
+ break;
597
+ }
598
+ }
599
+ }
600
+
601
+ write_tag(4);
602
+ more = visit_begin_array((std::size_t)2, semantic_tag::none, context, ec);
603
+ if (!more) {return more;}
604
+ if (exponent.length() > 0)
605
+ {
606
+ int64_t val;
607
+ auto r = jsoncons::detail::to_integer(exponent.data(), exponent.length(), val);
608
+ if (!r)
609
+ {
610
+ ec = r.error_code();
611
+ return false;
612
+ }
613
+ scale += val;
614
+ }
615
+ more = visit_int64(scale, semantic_tag::none, context, ec);
616
+ if (!more) {return more;}
617
+
618
+ int64_t val{ 0 };
619
+ auto r = jsoncons::detail::to_integer(s.data(),s.length(), val);
620
+ if (r)
621
+ {
622
+ more = visit_int64(val, semantic_tag::none, context, ec);
623
+ if (!more) {return more;}
624
+ }
625
+ else if (r.error_code() == jsoncons::detail::to_integer_errc::overflow)
626
+ {
627
+ bigint n = bigint::from_string(s.data(), s.length());
628
+ write_bignum(n);
629
+ end_value();
630
+ }
631
+ else
632
+ {
633
+ ec = r.error_code();
634
+ return false;
635
+ }
636
+ more = visit_end_array(context, ec);
637
+
638
+ return more;
639
+ }
640
+
641
+ bool write_hexfloat_value(const string_view_type& sv, const ser_context& context, std::error_code& ec)
642
+ {
643
+ bool more = true;
644
+
645
+ hexfloat_parse_state state = hexfloat_parse_state::start;
646
+ std::basic_string<char> s;
647
+ std::basic_string<char> exponent;
648
+ int64_t scale = 0;
649
+
650
+ for (auto c : sv)
651
+ {
652
+ switch (state)
653
+ {
654
+ case hexfloat_parse_state::start:
655
+ {
656
+ switch (c)
657
+ {
658
+ case '-':
659
+ s.push_back(c);
660
+ state = hexfloat_parse_state::expect_0;
661
+ break;
662
+ case '0':
663
+ state = hexfloat_parse_state::expect_x;
664
+ break;
665
+ default:
666
+ {
667
+ ec = cbor_errc::invalid_bigfloat;
668
+ return false;
669
+ }
670
+ }
671
+ break;
672
+ }
673
+ case hexfloat_parse_state::expect_0:
674
+ {
675
+ switch (c)
676
+ {
677
+ case '0':
678
+ state = hexfloat_parse_state::expect_x;
679
+ break;
680
+ default:
681
+ {
682
+ ec = cbor_errc::invalid_bigfloat;
683
+ return false;
684
+ }
685
+ }
686
+ break;
687
+ }
688
+ case hexfloat_parse_state::expect_x:
689
+ {
690
+ switch (c)
691
+ {
692
+ case 'x':
693
+ case 'X':
694
+ state = hexfloat_parse_state::integer;
695
+ break;
696
+ default:
697
+ {
698
+ ec = cbor_errc::invalid_bigfloat;
699
+ return false;
700
+ }
701
+ }
702
+ break;
703
+ }
704
+ case hexfloat_parse_state::integer:
705
+ {
706
+ switch (c)
707
+ {
708
+ case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':case 'a':case 'b':case 'c':case 'd':case 'e':case 'f':case 'A':case 'B':case 'C':case 'D':case 'E':case 'F':
709
+ s.push_back(c);
710
+ break;
711
+ case 'p': case 'P':
712
+ state = hexfloat_parse_state::exp1;
713
+ break;
714
+ case '.':
715
+ state = hexfloat_parse_state::fraction1;
716
+ break;
717
+ default:
718
+ {
719
+ ec = cbor_errc::invalid_bigfloat;
720
+ return false;
721
+ }
722
+ }
723
+ break;
724
+ }
725
+ case hexfloat_parse_state::exp1:
726
+ {
727
+ switch (c)
728
+ {
729
+ case '+':
730
+ state = hexfloat_parse_state::exp2;
731
+ break;
732
+ case '-':
733
+ exponent.push_back(c);
734
+ state = hexfloat_parse_state::exp2;
735
+ break;
736
+ case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':case 'a':case 'b':case 'c':case 'd':case 'e':case 'f':case 'A':case 'B':case 'C':case 'D':case 'E':case 'F':
737
+ exponent.push_back(c);
738
+ state = hexfloat_parse_state::exp2;
739
+ break;
740
+ default:
741
+ {
742
+ ec = cbor_errc::invalid_bigfloat;
743
+ return false;
744
+ }
745
+ }
746
+ break;
747
+ }
748
+ case hexfloat_parse_state::exp2:
749
+ {
750
+ switch (c)
751
+ {
752
+ case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':case 'a':case 'b':case 'c':case 'd':case 'e':case 'f':case 'A':case 'B':case 'C':case 'D':case 'E':case 'F':
753
+ exponent.push_back(c);
754
+ break;
755
+ default:
756
+ {
757
+ ec = cbor_errc::invalid_bigfloat;
758
+ return false;
759
+ }
760
+ }
761
+ break;
762
+ }
763
+ case hexfloat_parse_state::fraction1:
764
+ {
765
+ switch (c)
766
+ {
767
+ case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8': case '9':case 'a':case 'b':case 'c':case 'd':case 'e':case 'f':case 'A':case 'B':case 'C':case 'D':case 'E':case 'F':
768
+ s.push_back(c);
769
+ scale -= 4;
770
+ break;
771
+ default:
772
+ {
773
+ ec = cbor_errc::invalid_bigfloat;
774
+ return false;
775
+ }
776
+ }
777
+ break;
778
+ }
779
+ }
780
+ }
781
+
782
+ write_tag(5);
783
+ more = visit_begin_array((std::size_t)2, semantic_tag::none, context, ec);
784
+ if (!more) return more;
785
+
786
+ if (exponent.length() > 0)
787
+ {
788
+ int64_t val{ 0 };
789
+ auto r = jsoncons::detail::base16_to_integer(exponent.data(), exponent.length(), val);
790
+ if (!r)
791
+ {
792
+ ec = r.error_code();
793
+ return false;
794
+ }
795
+ scale += val;
796
+ }
797
+ more = visit_int64(scale, semantic_tag::none, context, ec);
798
+ if (!more) return more;
799
+
800
+ int64_t val{ 0 };
801
+ auto r = jsoncons::detail::base16_to_integer(s.data(),s.length(), val);
802
+ if (r)
803
+ {
804
+ more = visit_int64(val, semantic_tag::none, context, ec);
805
+ if (!more) return more;
806
+ }
807
+ else if (r.error_code() == jsoncons::detail::to_integer_errc::overflow)
808
+ {
809
+ bigint n = bigint::from_string_radix(s.data(), s.length(), 16);
810
+ write_bignum(n);
811
+ end_value();
812
+ }
813
+ else
814
+ {
815
+ JSONCONS_THROW(json_runtime_error<std::invalid_argument>(r.error_code().message()));
816
+ }
817
+ return visit_end_array(context, ec);
818
+ }
819
+
820
+ bool visit_string(const string_view_type& sv, semantic_tag tag, const ser_context& context, std::error_code& ec) override
821
+ {
822
+ switch (tag)
823
+ {
824
+ case semantic_tag::bigint:
825
+ {
826
+ bigint n = bigint::from_string(sv.data(), sv.length());
827
+ write_bignum(n);
828
+ end_value();
829
+ break;
830
+ }
831
+ case semantic_tag::bigdec:
832
+ {
833
+ return write_decimal_value(sv, context, ec);
834
+ }
835
+ case semantic_tag::bigfloat:
836
+ {
837
+ return write_hexfloat_value(sv, context, ec);
838
+ }
839
+ case semantic_tag::datetime:
840
+ {
841
+ write_tag(0);
842
+
843
+ write_string(sv);
844
+ end_value();
845
+ break;
846
+ }
847
+ case semantic_tag::uri:
848
+ {
849
+ write_tag(32);
850
+ write_string(sv);
851
+ end_value();
852
+ break;
853
+ }
854
+ case semantic_tag::base64url:
855
+ {
856
+ write_tag(33);
857
+ write_string(sv);
858
+ end_value();
859
+ break;
860
+ }
861
+ case semantic_tag::base64:
862
+ {
863
+ write_tag(34);
864
+ write_string(sv);
865
+ end_value();
866
+ break;
867
+ }
868
+ default:
869
+ {
870
+ write_string(sv);
871
+ end_value();
872
+ break;
873
+ }
874
+ }
875
+ return true;
876
+ }
877
+
878
+ bool visit_byte_string(const byte_string_view& b,
879
+ semantic_tag tag,
880
+ const ser_context&,
881
+ std::error_code&) override
882
+ {
883
+ byte_string_chars_format encoding_hint;
884
+ switch (tag)
885
+ {
886
+ case semantic_tag::base16:
887
+ encoding_hint = byte_string_chars_format::base16;
888
+ break;
889
+ case semantic_tag::base64:
890
+ encoding_hint = byte_string_chars_format::base64;
891
+ break;
892
+ case semantic_tag::base64url:
893
+ encoding_hint = byte_string_chars_format::base64url;
894
+ break;
895
+ default:
896
+ encoding_hint = byte_string_chars_format::none;
897
+ break;
898
+ }
899
+ switch (encoding_hint)
900
+ {
901
+ case byte_string_chars_format::base64url:
902
+ write_tag(21);
903
+ break;
904
+ case byte_string_chars_format::base64:
905
+ write_tag(22);
906
+ break;
907
+ case byte_string_chars_format::base16:
908
+ write_tag(23);
909
+ break;
910
+ default:
911
+ break;
912
+ }
913
+ if (options_.pack_strings() && b.size() >= jsoncons::cbor::detail::min_length_for_stringref(next_stringref_))
914
+ {
915
+ byte_string_type bs(b.data(), b.size(), alloc_);
916
+ auto it = bytestringref_map_.find(bs);
917
+ if (it == bytestringref_map_.end())
918
+ {
919
+ bytestringref_map_.emplace(std::make_pair(bs, next_stringref_++));
920
+ write_byte_string_value(bs);
921
+ }
922
+ else
923
+ {
924
+ write_tag(25);
925
+ write_uint64_value(it->second);
926
+ }
927
+ }
928
+ else
929
+ {
930
+ write_byte_string_value(b);
931
+ }
932
+
933
+ end_value();
934
+ return true;
935
+ }
936
+
937
+ bool visit_byte_string(const byte_string_view& b,
938
+ uint64_t ext_tag,
939
+ const ser_context&,
940
+ std::error_code&) override
941
+ {
942
+ if (options_.pack_strings() && b.size() >= jsoncons::cbor::detail::min_length_for_stringref(next_stringref_))
943
+ {
944
+ byte_string_type bs(b.data(), b.size(), alloc_);
945
+ auto it = bytestringref_map_.find(bs);
946
+ if (it == bytestringref_map_.end())
947
+ {
948
+ bytestringref_map_.emplace(std::make_pair(bs, next_stringref_++));
949
+ write_tag(ext_tag);
950
+ write_byte_string_value(bs);
951
+ }
952
+ else
953
+ {
954
+ write_tag(25);
955
+ write_uint64_value(it->second);
956
+ }
957
+ }
958
+ else
959
+ {
960
+ write_tag(ext_tag);
961
+ write_byte_string_value(b);
962
+ }
963
+
964
+ end_value();
965
+ return true;
966
+ }
967
+
968
+ void write_byte_string_value(const byte_string_view& b)
969
+ {
970
+ if (b.size() <= 0x17)
971
+ {
972
+ // fixstr stores a byte array whose length is upto 31 bytes
973
+ binary::native_to_big(static_cast<uint8_t>(0x40 + b.size()),
974
+ std::back_inserter(sink_));
975
+ }
976
+ else if (b.size() <= 0xff)
977
+ {
978
+ binary::native_to_big(static_cast<uint8_t>(0x58),
979
+ std::back_inserter(sink_));
980
+ binary::native_to_big(static_cast<uint8_t>(b.size()),
981
+ std::back_inserter(sink_));
982
+ }
983
+ else if (b.size() <= 0xffff)
984
+ {
985
+ binary::native_to_big(static_cast<uint8_t>(0x59),
986
+ std::back_inserter(sink_));
987
+ binary::native_to_big(static_cast<uint16_t>(b.size()),
988
+ std::back_inserter(sink_));
989
+ }
990
+ else if (b.size() <= 0xffffffff)
991
+ {
992
+ binary::native_to_big(static_cast<uint8_t>(0x5a),
993
+ std::back_inserter(sink_));
994
+ binary::native_to_big(static_cast<uint32_t>(b.size()),
995
+ std::back_inserter(sink_));
996
+ }
997
+ else // if (b.size() <= 0xffffffffffffffff)
998
+ {
999
+ binary::native_to_big(static_cast<uint8_t>(0x5b),
1000
+ std::back_inserter(sink_));
1001
+ binary::native_to_big(static_cast<uint64_t>(b.size()),
1002
+ std::back_inserter(sink_));
1003
+ }
1004
+
1005
+ for (auto c : b)
1006
+ {
1007
+ sink_.push_back(c);
1008
+ }
1009
+ }
1010
+
1011
+ bool visit_double(double val,
1012
+ semantic_tag tag,
1013
+ const ser_context&,
1014
+ std::error_code&) override
1015
+ {
1016
+ switch (tag)
1017
+ {
1018
+ case semantic_tag::epoch_second:
1019
+ write_tag(1);
1020
+ break;
1021
+ case semantic_tag::epoch_milli:
1022
+ write_tag(1);
1023
+ if (val != 0)
1024
+ {
1025
+ val /= millis_in_second;
1026
+ }
1027
+ break;
1028
+ case semantic_tag::epoch_nano:
1029
+ write_tag(1);
1030
+ if (val != 0)
1031
+ {
1032
+ val /= nanos_in_second;
1033
+ }
1034
+ break;
1035
+ default:
1036
+ break;
1037
+ }
1038
+
1039
+ float valf = (float)val;
1040
+ if ((double)valf == val)
1041
+ {
1042
+ binary::native_to_big(static_cast<uint8_t>(0xfa),
1043
+ std::back_inserter(sink_));
1044
+ binary::native_to_big(valf, std::back_inserter(sink_));
1045
+ }
1046
+ else
1047
+ {
1048
+ binary::native_to_big(static_cast<uint8_t>(0xfb),
1049
+ std::back_inserter(sink_));
1050
+ binary::native_to_big(val, std::back_inserter(sink_));
1051
+ }
1052
+
1053
+ // write double
1054
+
1055
+ end_value();
1056
+ return true;
1057
+ }
1058
+
1059
+ bool visit_int64(int64_t value,
1060
+ semantic_tag tag,
1061
+ const ser_context& context,
1062
+ std::error_code& ec) override
1063
+ {
1064
+ switch (tag)
1065
+ {
1066
+ case semantic_tag::epoch_milli:
1067
+ case semantic_tag::epoch_nano:
1068
+ return visit_double(static_cast<double>(value), tag, context, ec);
1069
+ case semantic_tag::epoch_second:
1070
+ write_tag(1);
1071
+ break;
1072
+ default:
1073
+ break;
1074
+ }
1075
+ if (value >= 0)
1076
+ {
1077
+ if (value <= 0x17)
1078
+ {
1079
+ binary::native_to_big(static_cast<uint8_t>(value),
1080
+ std::back_inserter(sink_));
1081
+ }
1082
+ else if (value <= (std::numeric_limits<uint8_t>::max)())
1083
+ {
1084
+ binary::native_to_big(static_cast<uint8_t>(0x18),
1085
+ std::back_inserter(sink_));
1086
+ binary::native_to_big(static_cast<uint8_t>(value),
1087
+ std::back_inserter(sink_));
1088
+ }
1089
+ else if (value <= (std::numeric_limits<uint16_t>::max)())
1090
+ {
1091
+ binary::native_to_big(static_cast<uint8_t>(0x19),
1092
+ std::back_inserter(sink_));
1093
+ binary::native_to_big(static_cast<uint16_t>(value),
1094
+ std::back_inserter(sink_));
1095
+ }
1096
+ else if (value <= (std::numeric_limits<uint32_t>::max)())
1097
+ {
1098
+ binary::native_to_big(static_cast<uint8_t>(0x1a),
1099
+ std::back_inserter(sink_));
1100
+ binary::native_to_big(static_cast<uint32_t>(value),
1101
+ std::back_inserter(sink_));
1102
+ }
1103
+ else if (value <= (std::numeric_limits<int64_t>::max)())
1104
+ {
1105
+ binary::native_to_big(static_cast<uint8_t>(0x1b),
1106
+ std::back_inserter(sink_));
1107
+ binary::native_to_big(static_cast<int64_t>(value),
1108
+ std::back_inserter(sink_));
1109
+ }
1110
+ } else
1111
+ {
1112
+ const auto posnum = -1 - value;
1113
+ if (value >= -24)
1114
+ {
1115
+ binary::native_to_big(static_cast<uint8_t>(0x20 + posnum),
1116
+ std::back_inserter(sink_));
1117
+ }
1118
+ else if (posnum <= (std::numeric_limits<uint8_t>::max)())
1119
+ {
1120
+ binary::native_to_big(static_cast<uint8_t>(0x38),
1121
+ std::back_inserter(sink_));
1122
+ binary::native_to_big(static_cast<uint8_t>(posnum),
1123
+ std::back_inserter(sink_));
1124
+ }
1125
+ else if (posnum <= (std::numeric_limits<uint16_t>::max)())
1126
+ {
1127
+ binary::native_to_big(static_cast<uint8_t>(0x39),
1128
+ std::back_inserter(sink_));
1129
+ binary::native_to_big(static_cast<uint16_t>(posnum),
1130
+ std::back_inserter(sink_));
1131
+ }
1132
+ else if (posnum <= (std::numeric_limits<uint32_t>::max)())
1133
+ {
1134
+ binary::native_to_big(static_cast<uint8_t>(0x3a),
1135
+ std::back_inserter(sink_));
1136
+ binary::native_to_big(static_cast<uint32_t>(posnum),
1137
+ std::back_inserter(sink_));
1138
+ }
1139
+ else if (posnum <= (std::numeric_limits<int64_t>::max)())
1140
+ {
1141
+ binary::native_to_big(static_cast<uint8_t>(0x3b),
1142
+ std::back_inserter(sink_));
1143
+ binary::native_to_big(static_cast<int64_t>(posnum),
1144
+ std::back_inserter(sink_));
1145
+ }
1146
+ }
1147
+ end_value();
1148
+ return true;
1149
+ }
1150
+
1151
+ bool visit_uint64(uint64_t value,
1152
+ semantic_tag tag,
1153
+ const ser_context& context,
1154
+ std::error_code& ec) override
1155
+ {
1156
+ switch (tag)
1157
+ {
1158
+ case semantic_tag::epoch_milli:
1159
+ case semantic_tag::epoch_nano:
1160
+ return visit_double(static_cast<double>(value), tag, context, ec);
1161
+ case semantic_tag::epoch_second:
1162
+ write_tag(1);
1163
+ break;
1164
+ default:
1165
+ break;
1166
+ }
1167
+
1168
+ write_uint64_value(value);
1169
+ end_value();
1170
+ return true;
1171
+ }
1172
+
1173
+ void write_tag(uint64_t value)
1174
+ {
1175
+ if (value <= 0x17)
1176
+ {
1177
+ sink_.push_back(0xc0 | static_cast<uint8_t>(value));
1178
+ }
1179
+ else if (value <=(std::numeric_limits<uint8_t>::max)())
1180
+ {
1181
+ sink_.push_back(0xd8);
1182
+ sink_.push_back(static_cast<uint8_t>(value));
1183
+ }
1184
+ else if (value <=(std::numeric_limits<uint16_t>::max)())
1185
+ {
1186
+ sink_.push_back(0xd9);
1187
+ binary::native_to_big(static_cast<uint16_t>(value),
1188
+ std::back_inserter(sink_));
1189
+ }
1190
+ else if (value <=(std::numeric_limits<uint32_t>::max)())
1191
+ {
1192
+ sink_.push_back(0xda);
1193
+ binary::native_to_big(static_cast<uint32_t>(value),
1194
+ std::back_inserter(sink_));
1195
+ }
1196
+ else
1197
+ {
1198
+ sink_.push_back(0xdb);
1199
+ binary::native_to_big(static_cast<uint64_t>(value),
1200
+ std::back_inserter(sink_));
1201
+ }
1202
+ }
1203
+
1204
+ void write_uint64_value(uint64_t value)
1205
+ {
1206
+ if (value <= 0x17)
1207
+ {
1208
+ sink_.push_back(static_cast<uint8_t>(value));
1209
+ }
1210
+ else if (value <=(std::numeric_limits<uint8_t>::max)())
1211
+ {
1212
+ sink_.push_back(static_cast<uint8_t>(0x18));
1213
+ sink_.push_back(static_cast<uint8_t>(value));
1214
+ }
1215
+ else if (value <=(std::numeric_limits<uint16_t>::max)())
1216
+ {
1217
+ sink_.push_back(static_cast<uint8_t>(0x19));
1218
+ binary::native_to_big(static_cast<uint16_t>(value),
1219
+ std::back_inserter(sink_));
1220
+ }
1221
+ else if (value <=(std::numeric_limits<uint32_t>::max)())
1222
+ {
1223
+ sink_.push_back(static_cast<uint8_t>(0x1a));
1224
+ binary::native_to_big(static_cast<uint32_t>(value),
1225
+ std::back_inserter(sink_));
1226
+ }
1227
+ else if (value <=(std::numeric_limits<uint64_t>::max)())
1228
+ {
1229
+ sink_.push_back(static_cast<uint8_t>(0x1b));
1230
+ binary::native_to_big(static_cast<uint64_t>(value),
1231
+ std::back_inserter(sink_));
1232
+ }
1233
+ }
1234
+
1235
+ bool visit_bool(bool value, semantic_tag, const ser_context&, std::error_code&) override
1236
+ {
1237
+ if (value)
1238
+ {
1239
+ sink_.push_back(0xf5);
1240
+ }
1241
+ else
1242
+ {
1243
+ sink_.push_back(0xf4);
1244
+ }
1245
+
1246
+ end_value();
1247
+ return true;
1248
+ }
1249
+
1250
+ bool visit_typed_array(const jsoncons::span<const uint8_t>& v,
1251
+ semantic_tag tag,
1252
+ const ser_context& context,
1253
+ std::error_code& ec) override
1254
+ {
1255
+ if (options_.use_typed_arrays())
1256
+ {
1257
+ switch (tag)
1258
+ {
1259
+ case semantic_tag::clamped:
1260
+ write_tag(0x44);
1261
+ break;
1262
+ default:
1263
+ write_tag(0x40);
1264
+ break;
1265
+ }
1266
+ write_byte_string_value(byte_string_view(v));
1267
+ return true;
1268
+ }
1269
+ else
1270
+ {
1271
+ bool more = this->begin_array(v.size(), semantic_tag::none, context, ec);
1272
+ for (auto p = v.begin(); more && p != v.end(); ++p)
1273
+ {
1274
+ more = this->uint64_value(*p, tag, context, ec);
1275
+ }
1276
+ if (more)
1277
+ {
1278
+ more = this->end_array(context, ec);
1279
+ }
1280
+ return more;
1281
+ }
1282
+ }
1283
+
1284
+ bool visit_typed_array(const jsoncons::span<const uint16_t>& data,
1285
+ semantic_tag tag,
1286
+ const ser_context& context,
1287
+ std::error_code& ec) override
1288
+ {
1289
+ if (options_.use_typed_arrays())
1290
+ {
1291
+ write_typed_array_tag(std::integral_constant<bool, jsoncons::endian::native == jsoncons::endian::big>(),
1292
+ uint16_t(),
1293
+ tag);
1294
+ std::vector<uint8_t> v(data.size()*sizeof(uint16_t));
1295
+ std::memcpy(v.data(),data.data(),data.size()*sizeof(uint16_t));
1296
+ write_byte_string_value(byte_string_view(v));
1297
+ return true;
1298
+ }
1299
+ else
1300
+ {
1301
+ bool more = this->begin_array(data.size(), semantic_tag::none, context, ec);
1302
+ for (auto p = data.begin(); more && p != data.end(); ++p)
1303
+ {
1304
+ more = this->uint64_value(*p, tag, context, ec);
1305
+ }
1306
+ if (more)
1307
+ {
1308
+ more = this->end_array(context, ec);
1309
+ }
1310
+ return more;
1311
+ }
1312
+ }
1313
+
1314
+ bool visit_typed_array(const jsoncons::span<const uint32_t>& data,
1315
+ semantic_tag tag,
1316
+ const ser_context& context,
1317
+ std::error_code& ec) override
1318
+ {
1319
+ if (options_.use_typed_arrays())
1320
+ {
1321
+ write_typed_array_tag(std::integral_constant<bool, jsoncons::endian::native == jsoncons::endian::big>(),
1322
+ uint32_t(),
1323
+ tag);
1324
+ std::vector<uint8_t> v(data.size()*sizeof(uint32_t));
1325
+ std::memcpy(v.data(), data.data(), data.size()*sizeof(uint32_t));
1326
+ write_byte_string_value(byte_string_view(v));
1327
+ return true;
1328
+ }
1329
+ else
1330
+ {
1331
+ bool more = this->begin_array(data.size(), semantic_tag::none, context, ec);
1332
+ for (auto p = data.begin(); more && p != data.end(); ++p)
1333
+ {
1334
+ more = this->uint64_value(*p, semantic_tag::none, context, ec);
1335
+ }
1336
+ if (more)
1337
+ {
1338
+ more = this->end_array(context, ec);
1339
+ }
1340
+ return more;
1341
+ }
1342
+ }
1343
+
1344
+ bool visit_typed_array(const jsoncons::span<const uint64_t>& data,
1345
+ semantic_tag tag,
1346
+ const ser_context& context,
1347
+ std::error_code& ec) override
1348
+ {
1349
+ if (options_.use_typed_arrays())
1350
+ {
1351
+ write_typed_array_tag(std::integral_constant<bool, jsoncons::endian::native == jsoncons::endian::big>(),
1352
+ uint64_t(),
1353
+ tag);
1354
+ std::vector<uint8_t> v(data.size()*sizeof(uint64_t));
1355
+ std::memcpy(v.data(), data.data(), data.size()*sizeof(uint64_t));
1356
+ write_byte_string_value(byte_string_view(v));
1357
+ return true;
1358
+ }
1359
+ else
1360
+ {
1361
+ bool more = this->begin_array(data.size(), semantic_tag::none, context, ec);
1362
+ for (auto p = data.begin(); more && p != data.end(); ++p)
1363
+ {
1364
+ more = this->uint64_value(*p,semantic_tag::none,context, ec);
1365
+ }
1366
+ if (more)
1367
+ {
1368
+ more = this->end_array(context, ec);
1369
+ }
1370
+ return more;
1371
+ }
1372
+ }
1373
+
1374
+ bool visit_typed_array(const jsoncons::span<const int8_t>& data,
1375
+ semantic_tag,
1376
+ const ser_context& context,
1377
+ std::error_code& ec) override
1378
+ {
1379
+ if (options_.use_typed_arrays())
1380
+ {
1381
+ write_tag(0x48);
1382
+ std::vector<uint8_t> v(data.size()*sizeof(int8_t));
1383
+ std::memcpy(v.data(), data.data(), data.size()*sizeof(int8_t));
1384
+ write_byte_string_value(byte_string_view(v));
1385
+ return true;
1386
+ }
1387
+ else
1388
+ {
1389
+ bool more = this->begin_array(data.size(), semantic_tag::none,context, ec);
1390
+ for (auto p = data.begin(); more && p != data.end(); ++p)
1391
+ {
1392
+ more = this->int64_value(*p,semantic_tag::none,context, ec);
1393
+ }
1394
+ if (more)
1395
+ {
1396
+ more = this->end_array(context, ec);
1397
+ }
1398
+ return more;
1399
+ }
1400
+ }
1401
+
1402
+ bool visit_typed_array(const jsoncons::span<const int16_t>& data,
1403
+ semantic_tag tag,
1404
+ const ser_context& context,
1405
+ std::error_code& ec) override
1406
+ {
1407
+ if (options_.use_typed_arrays())
1408
+ {
1409
+ write_typed_array_tag(std::integral_constant<bool, jsoncons::endian::native == jsoncons::endian::big>(),
1410
+ int16_t(),
1411
+ tag);
1412
+ std::vector<uint8_t> v(data.size()*sizeof(int16_t));
1413
+ std::memcpy(v.data(), data.data(), data.size()*sizeof(int16_t));
1414
+ write_byte_string_value(byte_string_view(v));
1415
+ return true;
1416
+ }
1417
+ else
1418
+ {
1419
+ bool more = this->begin_array(data.size(), semantic_tag::none,context, ec);
1420
+ for (auto p = data.begin(); more && p != data.end(); ++p)
1421
+ {
1422
+ more = this->int64_value(*p,semantic_tag::none,context, ec);
1423
+ }
1424
+ if (more)
1425
+ {
1426
+ more = this->end_array(context, ec);
1427
+ }
1428
+ return more;
1429
+ }
1430
+ }
1431
+
1432
+ bool visit_typed_array(const jsoncons::span<const int32_t>& data,
1433
+ semantic_tag tag,
1434
+ const ser_context& context,
1435
+ std::error_code& ec) override
1436
+ {
1437
+ if (options_.use_typed_arrays())
1438
+ {
1439
+ write_typed_array_tag(std::integral_constant<bool, jsoncons::endian::native == jsoncons::endian::big>(),
1440
+ int32_t(),
1441
+ tag);
1442
+ std::vector<uint8_t> v(data.size()*sizeof(int32_t));
1443
+ std::memcpy(v.data(), data.data(), data.size()*sizeof(int32_t));
1444
+ write_byte_string_value(byte_string_view(v));
1445
+ return true;
1446
+ }
1447
+ else
1448
+ {
1449
+ bool more = this->begin_array(data.size(), semantic_tag::none,context, ec);
1450
+ for (auto p = data.begin(); more && p != data.end(); ++p)
1451
+ {
1452
+ more = this->int64_value(*p,semantic_tag::none,context, ec);
1453
+ }
1454
+ if (more)
1455
+ {
1456
+ more = this->end_array(context, ec);
1457
+ }
1458
+ return more;
1459
+ }
1460
+ }
1461
+
1462
+ bool visit_typed_array(const jsoncons::span<const int64_t>& data,
1463
+ semantic_tag tag,
1464
+ const ser_context& context,
1465
+ std::error_code& ec) override
1466
+ {
1467
+ if (options_.use_typed_arrays())
1468
+ {
1469
+ write_typed_array_tag(std::integral_constant<bool, jsoncons::endian::native == jsoncons::endian::big>(),
1470
+ int64_t(),
1471
+ tag);
1472
+ std::vector<uint8_t> v(data.size()*sizeof(int64_t));
1473
+ std::memcpy(v.data(), data.data(), data.size()*sizeof(int64_t));
1474
+ write_byte_string_value(byte_string_view(v));
1475
+ return true;
1476
+ }
1477
+ else
1478
+ {
1479
+ bool more = this->begin_array(data.size(), semantic_tag::none,context, ec);
1480
+ for (auto p = data.begin(); more && p != data.end(); ++p)
1481
+ {
1482
+ more = this->int64_value(*p,semantic_tag::none,context, ec);
1483
+ }
1484
+ if (more)
1485
+ {
1486
+ more = this->end_array(context, ec);
1487
+ }
1488
+ return more;
1489
+ }
1490
+ }
1491
+
1492
+ bool visit_typed_array(half_arg_t, const jsoncons::span<const uint16_t>& data,
1493
+ semantic_tag tag,
1494
+ const ser_context& context,
1495
+ std::error_code& ec) override
1496
+ {
1497
+ if (options_.use_typed_arrays())
1498
+ {
1499
+ write_typed_array_tag(std::integral_constant<bool, jsoncons::endian::native == jsoncons::endian::big>(),
1500
+ half_arg,
1501
+ tag);
1502
+ std::vector<uint8_t> v(data.size()*sizeof(uint16_t));
1503
+ std::memcpy(v.data(),data.data(),data.size()*sizeof(uint16_t));
1504
+ write_byte_string_value(byte_string_view(v));
1505
+ return true;
1506
+ }
1507
+ else
1508
+ {
1509
+ bool more = this->begin_array(data.size(), semantic_tag::none, context, ec);
1510
+ for (auto p = data.begin(); more && p != data.end(); ++p)
1511
+ {
1512
+ more = this->half_value(*p, tag, context, ec);
1513
+ }
1514
+ if (more)
1515
+ {
1516
+ more = this->end_array(context, ec);
1517
+ }
1518
+ return more;
1519
+ }
1520
+ }
1521
+
1522
+ bool visit_typed_array(const jsoncons::span<const float>& data,
1523
+ semantic_tag tag,
1524
+ const ser_context& context,
1525
+ std::error_code& ec) override
1526
+ {
1527
+ if (options_.use_typed_arrays())
1528
+ {
1529
+ write_typed_array_tag(std::integral_constant<bool, jsoncons::endian::native == jsoncons::endian::big>(),
1530
+ float(),
1531
+ tag);
1532
+ std::vector<uint8_t> v(data.size()*sizeof(float));
1533
+ std::memcpy(v.data(), data.data(), data.size()*sizeof(float));
1534
+ write_byte_string_value(byte_string_view(v));
1535
+ return true;
1536
+ }
1537
+ else
1538
+ {
1539
+ bool more = this->begin_array(data.size(), semantic_tag::none,context, ec);
1540
+ for (auto p = data.begin(); more && p != data.end(); ++p)
1541
+ {
1542
+ more = this->double_value(*p,semantic_tag::none,context, ec);
1543
+ }
1544
+ if (more)
1545
+ {
1546
+ more = this->end_array(context, ec);
1547
+ }
1548
+ return more;
1549
+ }
1550
+ }
1551
+
1552
+ bool visit_typed_array(const jsoncons::span<const double>& data,
1553
+ semantic_tag tag,
1554
+ const ser_context& context,
1555
+ std::error_code& ec) override
1556
+ {
1557
+ if (options_.use_typed_arrays())
1558
+ {
1559
+ write_typed_array_tag(std::integral_constant<bool, jsoncons::endian::native == jsoncons::endian::big>(),
1560
+ double(),
1561
+ tag);
1562
+ std::vector<uint8_t> v(data.size()*sizeof(double));
1563
+ std::memcpy(v.data(), data.data(), data.size()*sizeof(double));
1564
+ write_byte_string_value(byte_string_view(v));
1565
+ return true;
1566
+ }
1567
+ else
1568
+ {
1569
+ bool more = this->begin_array(data.size(), semantic_tag::none,context, ec);
1570
+ for (auto p = data.begin(); more && p != data.end(); ++p)
1571
+ {
1572
+ more = this->double_value(*p,semantic_tag::none,context, ec);
1573
+ }
1574
+ if (more)
1575
+ {
1576
+ more = this->end_array(context, ec);
1577
+ }
1578
+ return more;
1579
+ }
1580
+ }
1581
+ /*
1582
+ bool visit_typed_array(const jsoncons::span<const float128_type>&,
1583
+ semantic_tag,
1584
+ const ser_context&,
1585
+ std::error_code&) override
1586
+ {
1587
+ return true;
1588
+ }
1589
+ */
1590
+ bool visit_begin_multi_dim(const jsoncons::span<const size_t>& shape,
1591
+ semantic_tag tag,
1592
+ const ser_context& context,
1593
+ std::error_code& ec) override
1594
+ {
1595
+ switch (tag)
1596
+ {
1597
+ case semantic_tag::multi_dim_column_major:
1598
+ write_tag(1040);
1599
+ break;
1600
+ default:
1601
+ write_tag(40);
1602
+ break;
1603
+ }
1604
+ bool more = visit_begin_array(2, semantic_tag::none, context, ec);
1605
+ if (more)
1606
+ more = visit_begin_array(shape.size(), semantic_tag::none, context, ec);
1607
+ for (auto it = shape.begin(); more && it != shape.end(); ++it)
1608
+ {
1609
+ more = visit_uint64(*it, semantic_tag::none, context, ec);
1610
+ }
1611
+ if (more)
1612
+ {
1613
+ more = visit_end_array(context, ec);
1614
+ }
1615
+ return more;
1616
+ }
1617
+
1618
+ bool visit_end_multi_dim(const ser_context& context,
1619
+ std::error_code& ec) override
1620
+ {
1621
+ bool more = visit_end_array(context, ec);
1622
+ return more;
1623
+ }
1624
+
1625
+ void write_typed_array_tag(std::true_type,
1626
+ uint16_t,
1627
+ semantic_tag)
1628
+ {
1629
+ write_tag(0x41); // big endian
1630
+ }
1631
+ void write_typed_array_tag(std::false_type,
1632
+ uint16_t,
1633
+ semantic_tag)
1634
+ {
1635
+ write_tag(0x45);
1636
+ }
1637
+
1638
+ void write_typed_array_tag(std::true_type,
1639
+ uint32_t,
1640
+ semantic_tag)
1641
+ {
1642
+ write_tag(0x42); // big endian
1643
+ }
1644
+ void write_typed_array_tag(std::false_type,
1645
+ uint32_t,
1646
+ semantic_tag)
1647
+ {
1648
+ write_tag(0x46); // little endian
1649
+ }
1650
+
1651
+ void write_typed_array_tag(std::true_type,
1652
+ uint64_t,
1653
+ semantic_tag)
1654
+ {
1655
+ write_tag(0x43); // big endian
1656
+ }
1657
+ void write_typed_array_tag(std::false_type,
1658
+ uint64_t,
1659
+ semantic_tag)
1660
+ {
1661
+ write_tag(0x47); // little endian
1662
+ }
1663
+
1664
+ void write_typed_array_tag(std::true_type,
1665
+ int16_t,
1666
+ semantic_tag)
1667
+ {
1668
+ write_tag(0x49); // big endian
1669
+ }
1670
+ void write_typed_array_tag(std::false_type,
1671
+ int16_t,
1672
+ semantic_tag)
1673
+ {
1674
+ write_tag(0x4d); // little endian
1675
+ }
1676
+
1677
+ void write_typed_array_tag(std::true_type,
1678
+ int32_t,
1679
+ semantic_tag)
1680
+ {
1681
+ write_tag(0x4a); // big endian
1682
+ }
1683
+ void write_typed_array_tag(std::false_type,
1684
+ int32_t,
1685
+ semantic_tag)
1686
+ {
1687
+ write_tag(0x4e); // little endian
1688
+ }
1689
+
1690
+ void write_typed_array_tag(std::true_type,
1691
+ int64_t,
1692
+ semantic_tag)
1693
+ {
1694
+ write_tag(0x4b); // big endian
1695
+ }
1696
+ void write_typed_array_tag(std::false_type,
1697
+ int64_t,
1698
+ semantic_tag)
1699
+ {
1700
+ write_tag(0x4f); // little endian
1701
+ }
1702
+
1703
+ void write_typed_array_tag(std::true_type,
1704
+ half_arg_t,
1705
+ semantic_tag)
1706
+ {
1707
+ write_tag(0x50);
1708
+ }
1709
+ void write_typed_array_tag(std::false_type,
1710
+ half_arg_t,
1711
+ semantic_tag)
1712
+ {
1713
+ write_tag(0x54);
1714
+ }
1715
+
1716
+ void write_typed_array_tag(std::true_type,
1717
+ float,
1718
+ semantic_tag)
1719
+ {
1720
+ write_tag(0x51); // big endian
1721
+ }
1722
+ void write_typed_array_tag(std::false_type,
1723
+ float,
1724
+ semantic_tag)
1725
+ {
1726
+ write_tag(0x55); // little endian
1727
+ }
1728
+
1729
+ void write_typed_array_tag(std::true_type,
1730
+ double,
1731
+ semantic_tag)
1732
+ {
1733
+ write_tag(0x52); // big endian
1734
+ }
1735
+ void write_typed_array_tag(std::false_type,
1736
+ double,
1737
+ semantic_tag)
1738
+ {
1739
+ write_tag(0x56); // little endian
1740
+ }
1741
+
1742
+ void end_value()
1743
+ {
1744
+ if (!stack_.empty())
1745
+ {
1746
+ ++stack_.back().count_;
1747
+ }
1748
+ }
1749
+ };
1750
+
1751
+ using cbor_stream_encoder = basic_cbor_encoder<jsoncons::binary_stream_sink>;
1752
+ using cbor_bytes_encoder = basic_cbor_encoder<jsoncons::bytes_sink<std::vector<uint8_t>>>;
1753
+
1754
+ #if !defined(JSONCONS_NO_DEPRECATED)
1755
+ JSONCONS_DEPRECATED_MSG("Instead, use cbor_bytes_encoder") typedef cbor_bytes_encoder cbor_bytes_serializer;
1756
+
1757
+ template<class Sink=jsoncons::binary_stream_sink>
1758
+ using basic_cbor_serializer = basic_cbor_encoder<Sink>;
1759
+
1760
+ JSONCONS_DEPRECATED_MSG("Instead, use cbor_stream_encoder") typedef cbor_stream_encoder cbor_encoder;
1761
+ JSONCONS_DEPRECATED_MSG("Instead, use cbor_stream_encoder") typedef cbor_stream_encoder cbor_serializer;
1762
+ JSONCONS_DEPRECATED_MSG("Instead, use cbor_bytes_encoder") typedef cbor_bytes_encoder cbor_buffer_serializer;
1763
+ #endif
1764
+
1765
+ }}
1766
+ #endif