jsoncons 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (155) hide show
  1. checksums.yaml +7 -0
  2. data/ext/jsoncons/extconf.rb +43 -0
  3. data/ext/jsoncons/jsoncons.cpp +161 -0
  4. data/ext/jsoncons/jsoncons.h +10 -0
  5. data/jsoncons.gemspec +44 -0
  6. data/lib/jsoncons/jsoncons/examples/input/address-book.json +13 -0
  7. data/lib/jsoncons/jsoncons/examples/input/books.json +28 -0
  8. data/lib/jsoncons/jsoncons/examples/input/countries.json +7 -0
  9. data/lib/jsoncons/jsoncons/examples/input/employees.json +30 -0
  10. data/lib/jsoncons/jsoncons/examples/input/jsonschema/name.json +15 -0
  11. data/lib/jsoncons/jsoncons/examples/input/multiple-json-objects.json +3 -0
  12. data/lib/jsoncons/jsoncons/examples/input/sales.csv +6 -0
  13. data/lib/jsoncons/jsoncons/examples/input/store.json +28 -0
  14. data/lib/jsoncons/jsoncons/examples/input/tasks.csv +6 -0
  15. data/lib/jsoncons/jsoncons/include/jsoncons/allocator_holder.hpp +38 -0
  16. data/lib/jsoncons/jsoncons/include/jsoncons/basic_json.hpp +5905 -0
  17. data/lib/jsoncons/jsoncons/include/jsoncons/bigint.hpp +1611 -0
  18. data/lib/jsoncons/jsoncons/include/jsoncons/byte_string.hpp +820 -0
  19. data/lib/jsoncons/jsoncons/include/jsoncons/config/binary_config.hpp +226 -0
  20. data/lib/jsoncons/jsoncons/include/jsoncons/config/compiler_support.hpp +375 -0
  21. data/lib/jsoncons/jsoncons/include/jsoncons/config/jsoncons_config.hpp +309 -0
  22. data/lib/jsoncons/jsoncons/include/jsoncons/config/version.hpp +40 -0
  23. data/lib/jsoncons/jsoncons/include/jsoncons/conv_error.hpp +218 -0
  24. data/lib/jsoncons/jsoncons/include/jsoncons/decode_json.hpp +209 -0
  25. data/lib/jsoncons/jsoncons/include/jsoncons/decode_traits.hpp +651 -0
  26. data/lib/jsoncons/jsoncons/include/jsoncons/detail/endian.hpp +44 -0
  27. data/lib/jsoncons/jsoncons/include/jsoncons/detail/grisu3.hpp +312 -0
  28. data/lib/jsoncons/jsoncons/include/jsoncons/detail/optional.hpp +483 -0
  29. data/lib/jsoncons/jsoncons/include/jsoncons/detail/parse_number.hpp +1133 -0
  30. data/lib/jsoncons/jsoncons/include/jsoncons/detail/span.hpp +188 -0
  31. data/lib/jsoncons/jsoncons/include/jsoncons/detail/string_view.hpp +537 -0
  32. data/lib/jsoncons/jsoncons/include/jsoncons/detail/string_wrapper.hpp +370 -0
  33. data/lib/jsoncons/jsoncons/include/jsoncons/detail/write_number.hpp +567 -0
  34. data/lib/jsoncons/jsoncons/include/jsoncons/encode_json.hpp +315 -0
  35. data/lib/jsoncons/jsoncons/include/jsoncons/encode_traits.hpp +378 -0
  36. data/lib/jsoncons/jsoncons/include/jsoncons/json.hpp +18 -0
  37. data/lib/jsoncons/jsoncons/include/jsoncons/json_array.hpp +324 -0
  38. data/lib/jsoncons/jsoncons/include/jsoncons/json_content_handler.hpp +12 -0
  39. data/lib/jsoncons/jsoncons/include/jsoncons/json_cursor.hpp +448 -0
  40. data/lib/jsoncons/jsoncons/include/jsoncons/json_decoder.hpp +420 -0
  41. data/lib/jsoncons/jsoncons/include/jsoncons/json_encoder.hpp +1587 -0
  42. data/lib/jsoncons/jsoncons/include/jsoncons/json_error.hpp +156 -0
  43. data/lib/jsoncons/jsoncons/include/jsoncons/json_exception.hpp +241 -0
  44. data/lib/jsoncons/jsoncons/include/jsoncons/json_filter.hpp +653 -0
  45. data/lib/jsoncons/jsoncons/include/jsoncons/json_fwd.hpp +23 -0
  46. data/lib/jsoncons/jsoncons/include/jsoncons/json_object.hpp +1772 -0
  47. data/lib/jsoncons/jsoncons/include/jsoncons/json_options.hpp +862 -0
  48. data/lib/jsoncons/jsoncons/include/jsoncons/json_parser.hpp +2900 -0
  49. data/lib/jsoncons/jsoncons/include/jsoncons/json_reader.hpp +731 -0
  50. data/lib/jsoncons/jsoncons/include/jsoncons/json_traits_macros.hpp +1072 -0
  51. data/lib/jsoncons/jsoncons/include/jsoncons/json_traits_macros_deprecated.hpp +144 -0
  52. data/lib/jsoncons/jsoncons/include/jsoncons/json_type.hpp +206 -0
  53. data/lib/jsoncons/jsoncons/include/jsoncons/json_type_traits.hpp +1830 -0
  54. data/lib/jsoncons/jsoncons/include/jsoncons/json_visitor.hpp +1560 -0
  55. data/lib/jsoncons/jsoncons/include/jsoncons/json_visitor2.hpp +2079 -0
  56. data/lib/jsoncons/jsoncons/include/jsoncons/pretty_print.hpp +89 -0
  57. data/lib/jsoncons/jsoncons/include/jsoncons/ser_context.hpp +62 -0
  58. data/lib/jsoncons/jsoncons/include/jsoncons/sink.hpp +289 -0
  59. data/lib/jsoncons/jsoncons/include/jsoncons/source.hpp +777 -0
  60. data/lib/jsoncons/jsoncons/include/jsoncons/source_adaptor.hpp +148 -0
  61. data/lib/jsoncons/jsoncons/include/jsoncons/staj2_cursor.hpp +1189 -0
  62. data/lib/jsoncons/jsoncons/include/jsoncons/staj_cursor.hpp +1254 -0
  63. data/lib/jsoncons/jsoncons/include/jsoncons/staj_iterator.hpp +449 -0
  64. data/lib/jsoncons/jsoncons/include/jsoncons/tag_type.hpp +245 -0
  65. data/lib/jsoncons/jsoncons/include/jsoncons/text_source_adaptor.hpp +144 -0
  66. data/lib/jsoncons/jsoncons/include/jsoncons/traits_extension.hpp +884 -0
  67. data/lib/jsoncons/jsoncons/include/jsoncons/typed_array_view.hpp +250 -0
  68. data/lib/jsoncons/jsoncons/include/jsoncons/unicode_traits.hpp +1330 -0
  69. data/lib/jsoncons/jsoncons/include/jsoncons/uri.hpp +635 -0
  70. data/lib/jsoncons/jsoncons/include/jsoncons/value_converter.hpp +340 -0
  71. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson.hpp +23 -0
  72. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_cursor.hpp +320 -0
  73. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_decimal128.hpp +865 -0
  74. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_encoder.hpp +585 -0
  75. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_error.hpp +103 -0
  76. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_oid.hpp +245 -0
  77. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_options.hpp +75 -0
  78. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_parser.hpp +645 -0
  79. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_reader.hpp +92 -0
  80. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_type.hpp +44 -0
  81. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/decode_bson.hpp +201 -0
  82. data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/encode_bson.hpp +144 -0
  83. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor.hpp +26 -0
  84. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_cursor.hpp +351 -0
  85. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_cursor2.hpp +265 -0
  86. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_detail.hpp +93 -0
  87. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_encoder.hpp +1766 -0
  88. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_error.hpp +105 -0
  89. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_options.hpp +113 -0
  90. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_parser.hpp +1942 -0
  91. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_reader.hpp +116 -0
  92. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/decode_cbor.hpp +203 -0
  93. data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/encode_cbor.hpp +151 -0
  94. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv.hpp +17 -0
  95. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_cursor.hpp +358 -0
  96. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_encoder.hpp +954 -0
  97. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_error.hpp +85 -0
  98. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_options.hpp +973 -0
  99. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_parser.hpp +2099 -0
  100. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_reader.hpp +348 -0
  101. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_serializer.hpp +12 -0
  102. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/decode_csv.hpp +208 -0
  103. data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/encode_csv.hpp +122 -0
  104. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jmespath/jmespath.hpp +5215 -0
  105. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jmespath/jmespath_error.hpp +215 -0
  106. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpatch/jsonpatch.hpp +579 -0
  107. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpatch/jsonpatch_error.hpp +121 -0
  108. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/expression.hpp +3329 -0
  109. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/flatten.hpp +432 -0
  110. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/json_location.hpp +445 -0
  111. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/json_query.hpp +115 -0
  112. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/jsonpath.hpp +13 -0
  113. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/jsonpath_error.hpp +240 -0
  114. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/jsonpath_expression.hpp +2612 -0
  115. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/jsonpath_selector.hpp +1322 -0
  116. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpointer/jsonpointer.hpp +1577 -0
  117. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpointer/jsonpointer_error.hpp +119 -0
  118. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/format_validator.hpp +968 -0
  119. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/json_validator.hpp +120 -0
  120. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/jsonschema.hpp +13 -0
  121. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/jsonschema_error.hpp +105 -0
  122. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/jsonschema_version.hpp +18 -0
  123. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/keyword_validator.hpp +1745 -0
  124. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/keyword_validator_factory.hpp +556 -0
  125. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/schema_draft7.hpp +198 -0
  126. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/schema_location.hpp +200 -0
  127. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/schema_version.hpp +35 -0
  128. data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/subschema.hpp +144 -0
  129. data/lib/jsoncons/jsoncons/include/jsoncons_ext/mergepatch/mergepatch.hpp +103 -0
  130. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/decode_msgpack.hpp +202 -0
  131. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/encode_msgpack.hpp +142 -0
  132. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack.hpp +24 -0
  133. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_cursor.hpp +343 -0
  134. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_cursor2.hpp +259 -0
  135. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_encoder.hpp +753 -0
  136. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_error.hpp +94 -0
  137. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_options.hpp +74 -0
  138. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_parser.hpp +748 -0
  139. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_reader.hpp +116 -0
  140. data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_type.hpp +63 -0
  141. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/decode_ubjson.hpp +201 -0
  142. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/encode_ubjson.hpp +142 -0
  143. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson.hpp +23 -0
  144. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_cursor.hpp +307 -0
  145. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_encoder.hpp +502 -0
  146. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_error.hpp +100 -0
  147. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_options.hpp +87 -0
  148. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_parser.hpp +880 -0
  149. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_reader.hpp +92 -0
  150. data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_type.hpp +43 -0
  151. data/lib/jsoncons/version.rb +5 -0
  152. data/lib/jsoncons.rb +33 -0
  153. data/test/jsoncons_test.rb +108 -0
  154. data/test/test_helper.rb +7 -0
  155. metadata +268 -0
@@ -0,0 +1,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