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,753 @@
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_MSGPACK_MSGPACK_ENCODER_HPP
8
+ #define JSONCONS_MSGPACK_MSGPACK_ENCODER_HPP
9
+
10
+ #include <string>
11
+ #include <vector>
12
+ #include <limits> // std::numeric_limits
13
+ #include <memory>
14
+ #include <utility> // std::move
15
+ #include <jsoncons/json_exception.hpp>
16
+ #include <jsoncons/json_visitor.hpp>
17
+ #include <jsoncons/config/jsoncons_config.hpp>
18
+ #include <jsoncons/sink.hpp>
19
+ #include <jsoncons/detail/parse_number.hpp>
20
+ #include <jsoncons_ext/msgpack/msgpack_type.hpp>
21
+ #include <jsoncons_ext/msgpack/msgpack_error.hpp>
22
+ #include <jsoncons_ext/msgpack/msgpack_options.hpp>
23
+
24
+ namespace jsoncons {
25
+ namespace msgpack {
26
+
27
+ enum class msgpack_container_type {object, array};
28
+
29
+ template<class Sink=jsoncons::binary_stream_sink,class Allocator=std::allocator<char>>
30
+ class basic_msgpack_encoder final : public basic_json_visitor<char>
31
+ {
32
+ enum class decimal_parse_state { start, integer, exp1, exp2, fraction1 };
33
+
34
+ static constexpr int64_t nanos_in_milli = 1000000;
35
+ static constexpr int64_t nanos_in_second = 1000000000;
36
+ static constexpr int64_t millis_in_second = 1000;
37
+ public:
38
+ using allocator_type = Allocator;
39
+ using char_type = char;
40
+ using typename basic_json_visitor<char>::string_view_type;
41
+ using sink_type = Sink;
42
+
43
+ private:
44
+ struct stack_item
45
+ {
46
+ msgpack_container_type type_;
47
+ std::size_t length_;
48
+ std::size_t count_;
49
+
50
+ stack_item(msgpack_container_type type, std::size_t length = 0) noexcept
51
+ : type_(type), length_(length), count_(0)
52
+ {
53
+ }
54
+
55
+ std::size_t length() const
56
+ {
57
+ return length_;
58
+ }
59
+
60
+ std::size_t count() const
61
+ {
62
+ return count_;
63
+ }
64
+
65
+ bool is_object() const
66
+ {
67
+ return type_ == msgpack_container_type::object;
68
+ }
69
+ };
70
+
71
+ Sink sink_;
72
+ const msgpack_encode_options options_;
73
+ allocator_type alloc_;
74
+
75
+ std::vector<stack_item> stack_;
76
+ int nesting_depth_;
77
+
78
+ // Noncopyable and nonmoveable
79
+ basic_msgpack_encoder(const basic_msgpack_encoder&) = delete;
80
+ basic_msgpack_encoder& operator=(const basic_msgpack_encoder&) = delete;
81
+ public:
82
+ explicit basic_msgpack_encoder(Sink&& sink,
83
+ const Allocator& alloc = Allocator())
84
+ : basic_msgpack_encoder(std::forward<Sink>(sink), msgpack_encode_options(), alloc)
85
+ {
86
+ }
87
+
88
+ explicit basic_msgpack_encoder(Sink&& sink,
89
+ const msgpack_encode_options& options,
90
+ const Allocator& alloc = Allocator())
91
+ : sink_(std::forward<Sink>(sink)),
92
+ options_(options),
93
+ alloc_(alloc),
94
+ nesting_depth_(0)
95
+ {
96
+ }
97
+
98
+ ~basic_msgpack_encoder() noexcept
99
+ {
100
+ sink_.flush();
101
+ }
102
+
103
+ void reset()
104
+ {
105
+ stack_.clear();
106
+ nesting_depth_ = 0;
107
+ }
108
+
109
+ void reset(Sink&& sink)
110
+ {
111
+ sink_ = std::move(sink);
112
+ reset();
113
+ }
114
+
115
+ private:
116
+ // Implementing methods
117
+
118
+ void visit_flush() override
119
+ {
120
+ sink_.flush();
121
+ }
122
+
123
+ bool visit_begin_object(semantic_tag, const ser_context&, std::error_code& ec) override
124
+ {
125
+ ec = msgpack_errc::object_length_required;
126
+ return false;
127
+ }
128
+
129
+ bool visit_begin_object(std::size_t length, semantic_tag, const ser_context&, std::error_code& ec) override
130
+ {
131
+ if (JSONCONS_UNLIKELY(++nesting_depth_ > options_.max_nesting_depth()))
132
+ {
133
+ ec = msgpack_errc::max_nesting_depth_exceeded;
134
+ return false;
135
+ }
136
+ stack_.emplace_back(msgpack_container_type::object, length);
137
+
138
+ if (length <= 15)
139
+ {
140
+ // fixmap
141
+ sink_.push_back(jsoncons::msgpack::msgpack_type::fixmap_base_type | (length & 0xf));
142
+ }
143
+ else if (length <= 65535)
144
+ {
145
+ // map 16
146
+ sink_.push_back(jsoncons::msgpack::msgpack_type::map16_type);
147
+ binary::native_to_big(static_cast<uint16_t>(length),
148
+ std::back_inserter(sink_));
149
+ }
150
+ else if (length <= 4294967295)
151
+ {
152
+ // map 32
153
+ sink_.push_back(jsoncons::msgpack::msgpack_type::map32_type);
154
+ binary::native_to_big(static_cast<uint32_t>(length),
155
+ std::back_inserter(sink_));
156
+ }
157
+
158
+ return true;
159
+ }
160
+
161
+ bool visit_end_object(const ser_context&, std::error_code& ec) override
162
+ {
163
+ JSONCONS_ASSERT(!stack_.empty());
164
+ --nesting_depth_;
165
+
166
+ if (stack_.back().count() < stack_.back().length())
167
+ {
168
+ ec = msgpack_errc::too_few_items;
169
+ return false;
170
+ }
171
+ else if (stack_.back().count() > stack_.back().length())
172
+ {
173
+ ec = msgpack_errc::too_many_items;
174
+ return false;
175
+ }
176
+
177
+ stack_.pop_back();
178
+ end_value();
179
+ return true;
180
+ }
181
+
182
+ bool visit_begin_array(semantic_tag, const ser_context&, std::error_code& ec) override
183
+ {
184
+ ec = msgpack_errc::array_length_required;
185
+ return false;
186
+ }
187
+
188
+ bool visit_begin_array(std::size_t length, semantic_tag, const ser_context&, std::error_code& ec) override
189
+ {
190
+ if (JSONCONS_UNLIKELY(++nesting_depth_ > options_.max_nesting_depth()))
191
+ {
192
+ ec = msgpack_errc::max_nesting_depth_exceeded;
193
+ return false;
194
+ }
195
+ stack_.emplace_back(msgpack_container_type::array, length);
196
+ if (length <= 15)
197
+ {
198
+ // fixarray
199
+ sink_.push_back(jsoncons::msgpack::msgpack_type::fixarray_base_type | (length & 0xf));
200
+ }
201
+ else if (length <= (std::numeric_limits<uint16_t>::max)())
202
+ {
203
+ // array 16
204
+ sink_.push_back(jsoncons::msgpack::msgpack_type::array16_type);
205
+ binary::native_to_big(static_cast<uint16_t>(length),std::back_inserter(sink_));
206
+ }
207
+ else if (length <= (std::numeric_limits<uint32_t>::max)())
208
+ {
209
+ // array 32
210
+ sink_.push_back(jsoncons::msgpack::msgpack_type::array32_type);
211
+ binary::native_to_big(static_cast<uint32_t>(length),std::back_inserter(sink_));
212
+ }
213
+ return true;
214
+ }
215
+
216
+ bool visit_end_array(const ser_context&, std::error_code& ec) override
217
+ {
218
+ JSONCONS_ASSERT(!stack_.empty());
219
+
220
+ --nesting_depth_;
221
+
222
+ if (stack_.back().count() < stack_.back().length())
223
+ {
224
+ ec = msgpack_errc::too_few_items;
225
+ return false;
226
+ }
227
+ else if (stack_.back().count() > stack_.back().length())
228
+ {
229
+ ec = msgpack_errc::too_many_items;
230
+ return false;
231
+ }
232
+
233
+ stack_.pop_back();
234
+ end_value();
235
+ return true;
236
+ }
237
+
238
+ bool visit_key(const string_view_type& name, const ser_context&, std::error_code&) override
239
+ {
240
+ write_string_value(name);
241
+ return true;
242
+ }
243
+
244
+ bool visit_null(semantic_tag, const ser_context&, std::error_code&) override
245
+ {
246
+ // nil
247
+ sink_.push_back(jsoncons::msgpack::msgpack_type::nil_type);
248
+ end_value();
249
+ return true;
250
+ }
251
+
252
+ void write_timestamp(int64_t seconds, int64_t nanoseconds)
253
+ {
254
+ if ((seconds >> 34) == 0)
255
+ {
256
+ uint64_t data64 = (nanoseconds << 34) | seconds;
257
+ if ((data64 & 0xffffffff00000000L) == 0)
258
+ {
259
+ // timestamp 32
260
+ sink_.push_back(jsoncons::msgpack::msgpack_type::fixext4_type);
261
+ sink_.push_back(0xff);
262
+ binary::native_to_big(static_cast<uint32_t>(data64), std::back_inserter(sink_));
263
+ }
264
+ else
265
+ {
266
+ // timestamp 64
267
+ sink_.push_back(jsoncons::msgpack::msgpack_type::fixext8_type);
268
+ sink_.push_back(0xff);
269
+ binary::native_to_big(static_cast<uint64_t>(data64), std::back_inserter(sink_));
270
+ }
271
+ }
272
+ else
273
+ {
274
+ // timestamp 96
275
+ sink_.push_back(jsoncons::msgpack::msgpack_type::ext8_type);
276
+ sink_.push_back(0x0c); // 12
277
+ sink_.push_back(0xff);
278
+ binary::native_to_big(static_cast<uint32_t>(nanoseconds), std::back_inserter(sink_));
279
+ binary::native_to_big(static_cast<uint64_t>(seconds), std::back_inserter(sink_));
280
+ }
281
+ }
282
+
283
+ bool visit_string(const string_view_type& sv, semantic_tag tag, const ser_context&, std::error_code& ec) override
284
+ {
285
+ switch (tag)
286
+ {
287
+ case semantic_tag::epoch_second:
288
+ {
289
+ int64_t seconds;
290
+ auto result = jsoncons::detail::to_integer(sv.data(), sv.length(), seconds);
291
+ if (!result)
292
+ {
293
+ ec = msgpack_errc::invalid_timestamp;
294
+ return false;
295
+ }
296
+ write_timestamp(seconds, 0);
297
+ break;
298
+ }
299
+ case semantic_tag::epoch_milli:
300
+ {
301
+ bigint n = bigint::from_string(sv.data(), sv.length());
302
+ if (n != 0)
303
+ {
304
+ bigint q;
305
+ bigint rem;
306
+ n.divide(millis_in_second, q, rem, true);
307
+ int64_t seconds = static_cast<int64_t>(q);
308
+ int64_t nanoseconds = static_cast<int64_t>(rem) * nanos_in_milli;
309
+ if (nanoseconds < 0)
310
+ {
311
+ nanoseconds = -nanoseconds;
312
+ }
313
+ write_timestamp(seconds, nanoseconds);
314
+ }
315
+ else
316
+ {
317
+ write_timestamp(0, 0);
318
+ }
319
+ break;
320
+ }
321
+ case semantic_tag::epoch_nano:
322
+ {
323
+ bigint n = bigint::from_string(sv.data(), sv.length());
324
+ if (n != 0)
325
+ {
326
+ bigint q;
327
+ bigint rem;
328
+ n.divide(nanos_in_second, q, rem, true);
329
+ int64_t seconds = static_cast<int64_t>(q);
330
+ int64_t nanoseconds = static_cast<int64_t>(rem);
331
+ if (nanoseconds < 0)
332
+ {
333
+ nanoseconds = -nanoseconds;
334
+ }
335
+ write_timestamp(seconds, nanoseconds);
336
+ }
337
+ else
338
+ {
339
+ write_timestamp(0, 0);
340
+ }
341
+ break;
342
+ }
343
+ default:
344
+ {
345
+ write_string_value(sv);
346
+ end_value();
347
+ break;
348
+ }
349
+ }
350
+ return true;
351
+ }
352
+
353
+ void write_string_value(const string_view_type& sv)
354
+ {
355
+ auto sink = unicode_traits::validate(sv.data(), sv.size());
356
+ if (sink.ec != unicode_traits::conv_errc())
357
+ {
358
+ JSONCONS_THROW(ser_error(msgpack_errc::invalid_utf8_text_string));
359
+ }
360
+
361
+ const size_t length = sv.length();
362
+ if (length <= 31)
363
+ {
364
+ // fixstr stores a byte array whose length is upto 31 bytes
365
+ sink_.push_back(jsoncons::msgpack::msgpack_type::fixstr_base_type | static_cast<uint8_t>(length));
366
+ }
367
+ else if (length <= (std::numeric_limits<uint8_t>::max)())
368
+ {
369
+ // str 8 stores a byte array whose length is upto (2^8)-1 bytes
370
+ sink_.push_back(jsoncons::msgpack::msgpack_type::str8_type);
371
+ sink_.push_back(static_cast<uint8_t>(length));
372
+ }
373
+ else if (length <= (std::numeric_limits<uint16_t>::max)())
374
+ {
375
+ // str 16 stores a byte array whose length is upto (2^16)-1 bytes
376
+ sink_.push_back(jsoncons::msgpack::msgpack_type::str16_type);
377
+ binary::native_to_big(static_cast<uint16_t>(length), std::back_inserter(sink_));
378
+ }
379
+ else if (length <= (std::numeric_limits<uint32_t>::max)())
380
+ {
381
+ // str 32 stores a byte array whose length is upto (2^32)-1 bytes
382
+ sink_.push_back(jsoncons::msgpack::msgpack_type::str32_type);
383
+ binary::native_to_big(static_cast<uint32_t>(length),std::back_inserter(sink_));
384
+ }
385
+
386
+ for (auto c : sv)
387
+ {
388
+ sink_.push_back(c);
389
+ }
390
+ }
391
+
392
+ bool visit_byte_string(const byte_string_view& b,
393
+ semantic_tag,
394
+ const ser_context&,
395
+ std::error_code&) override
396
+ {
397
+
398
+ const std::size_t length = b.size();
399
+ if (length <= (std::numeric_limits<uint8_t>::max)())
400
+ {
401
+ // bin 8 stores a byte array whose length is upto (2^8)-1 bytes
402
+ sink_.push_back(jsoncons::msgpack::msgpack_type::bin8_type);
403
+ sink_.push_back(static_cast<uint8_t>(length));
404
+ }
405
+ else if (length <= (std::numeric_limits<uint16_t>::max)())
406
+ {
407
+ // bin 16 stores a byte array whose length is upto (2^16)-1 bytes
408
+ sink_.push_back(jsoncons::msgpack::msgpack_type::bin16_type);
409
+ binary::native_to_big(static_cast<uint16_t>(length), std::back_inserter(sink_));
410
+ }
411
+ else if (length <= (std::numeric_limits<uint32_t>::max)())
412
+ {
413
+ // bin 32 stores a byte array whose length is upto (2^32)-1 bytes
414
+ sink_.push_back(jsoncons::msgpack::msgpack_type::bin32_type);
415
+ binary::native_to_big(static_cast<uint32_t>(length),std::back_inserter(sink_));
416
+ }
417
+
418
+ for (auto c : b)
419
+ {
420
+ sink_.push_back(c);
421
+ }
422
+
423
+ end_value();
424
+ return true;
425
+ }
426
+
427
+ bool visit_byte_string(const byte_string_view& b,
428
+ uint64_t ext_tag,
429
+ const ser_context&,
430
+ std::error_code&) override
431
+ {
432
+ const std::size_t length = b.size();
433
+ switch (length)
434
+ {
435
+ case 1:
436
+ sink_.push_back(jsoncons::msgpack::msgpack_type::fixext1_type);
437
+ sink_.push_back(static_cast<uint8_t>(ext_tag));
438
+ break;
439
+ case 2:
440
+ sink_.push_back(jsoncons::msgpack::msgpack_type::fixext2_type);
441
+ sink_.push_back(static_cast<uint8_t>(ext_tag));
442
+ break;
443
+ case 4:
444
+ sink_.push_back(jsoncons::msgpack::msgpack_type::fixext4_type);
445
+ sink_.push_back(static_cast<uint8_t>(ext_tag));
446
+ break;
447
+ case 8:
448
+ sink_.push_back(jsoncons::msgpack::msgpack_type::fixext8_type);
449
+ sink_.push_back(static_cast<uint8_t>(ext_tag));
450
+ break;
451
+ case 16:
452
+ sink_.push_back(jsoncons::msgpack::msgpack_type::fixext16_type);
453
+ sink_.push_back(static_cast<uint8_t>(ext_tag));
454
+ break;
455
+ default:
456
+ if (length <= (std::numeric_limits<uint8_t>::max)())
457
+ {
458
+ sink_.push_back(jsoncons::msgpack::msgpack_type::ext8_type);
459
+ sink_.push_back(static_cast<uint8_t>(length));
460
+ sink_.push_back(static_cast<uint8_t>(ext_tag));
461
+ }
462
+ else if (length <= (std::numeric_limits<uint16_t>::max)())
463
+ {
464
+ sink_.push_back(jsoncons::msgpack::msgpack_type::ext16_type);
465
+ binary::native_to_big(static_cast<uint16_t>(length), std::back_inserter(sink_));
466
+ sink_.push_back(static_cast<uint8_t>(ext_tag));
467
+ }
468
+ else if (length <= (std::numeric_limits<uint32_t>::max)())
469
+ {
470
+ sink_.push_back(jsoncons::msgpack::msgpack_type::ext32_type);
471
+ binary::native_to_big(static_cast<uint32_t>(length),std::back_inserter(sink_));
472
+ sink_.push_back(static_cast<uint8_t>(ext_tag));
473
+ }
474
+ break;
475
+ }
476
+
477
+ for (auto c : b)
478
+ {
479
+ sink_.push_back(c);
480
+ }
481
+
482
+ end_value();
483
+ return true;
484
+ }
485
+
486
+ bool visit_double(double val,
487
+ semantic_tag,
488
+ const ser_context&,
489
+ std::error_code&) override
490
+ {
491
+ float valf = (float)val;
492
+ if ((double)valf == val)
493
+ {
494
+ // float 32
495
+ sink_.push_back(jsoncons::msgpack::msgpack_type::float32_type);
496
+ binary::native_to_big(valf,std::back_inserter(sink_));
497
+ }
498
+ else
499
+ {
500
+ // float 64
501
+ sink_.push_back(jsoncons::msgpack::msgpack_type::float64_type);
502
+ binary::native_to_big(val,std::back_inserter(sink_));
503
+ }
504
+
505
+ // write double
506
+
507
+ end_value();
508
+ return true;
509
+ }
510
+
511
+ bool visit_int64(int64_t val,
512
+ semantic_tag tag,
513
+ const ser_context&,
514
+ std::error_code&) override
515
+ {
516
+ switch (tag)
517
+ {
518
+ case semantic_tag::epoch_second:
519
+ write_timestamp(val, 0);
520
+ break;
521
+ case semantic_tag::epoch_milli:
522
+ {
523
+ if (val != 0)
524
+ {
525
+ auto dv = std::div(val,millis_in_second);
526
+ int64_t seconds = dv.quot;
527
+ int64_t nanoseconds = dv.rem*nanos_in_milli;
528
+ if (nanoseconds < 0)
529
+ {
530
+ nanoseconds = -nanoseconds;
531
+ }
532
+ write_timestamp(seconds, nanoseconds);
533
+ }
534
+ else
535
+ {
536
+ write_timestamp(0, 0);
537
+ }
538
+ break;
539
+ }
540
+ case semantic_tag::epoch_nano:
541
+ {
542
+ if (val != 0)
543
+ {
544
+ auto dv = std::div(val,static_cast<int64_t>(nanos_in_second));
545
+ int64_t seconds = dv.quot;
546
+ int64_t nanoseconds = dv.rem;
547
+ if (nanoseconds < 0)
548
+ {
549
+ nanoseconds = -nanoseconds;
550
+ }
551
+ write_timestamp(seconds, nanoseconds);
552
+ }
553
+ else
554
+ {
555
+ write_timestamp(0, 0);
556
+ }
557
+ break;
558
+ }
559
+ default:
560
+ {
561
+ if (val >= 0)
562
+ {
563
+ if (val <= 0x7f)
564
+ {
565
+ // positive fixnum stores 7-bit positive integer
566
+ sink_.push_back(static_cast<uint8_t>(val));
567
+ }
568
+ else if (val <= (std::numeric_limits<uint8_t>::max)())
569
+ {
570
+ // uint 8 stores a 8-bit unsigned integer
571
+ sink_.push_back(jsoncons::msgpack::msgpack_type::uint8_type);
572
+ sink_.push_back(static_cast<uint8_t>(val));
573
+ }
574
+ else if (val <= (std::numeric_limits<uint16_t>::max)())
575
+ {
576
+ // uint 16 stores a 16-bit big-endian unsigned integer
577
+ sink_.push_back(jsoncons::msgpack::msgpack_type::uint16_type);
578
+ binary::native_to_big(static_cast<uint16_t>(val),std::back_inserter(sink_));
579
+ }
580
+ else if (val <= (std::numeric_limits<uint32_t>::max)())
581
+ {
582
+ // uint 32 stores a 32-bit big-endian unsigned integer
583
+ sink_.push_back(jsoncons::msgpack::msgpack_type::uint32_type);
584
+ binary::native_to_big(static_cast<uint32_t>(val),std::back_inserter(sink_));
585
+ }
586
+ else if (val <= (std::numeric_limits<int64_t>::max)())
587
+ {
588
+ // int 64 stores a 64-bit big-endian signed integer
589
+ sink_.push_back(jsoncons::msgpack::msgpack_type::uint64_type);
590
+ binary::native_to_big(static_cast<uint64_t>(val),std::back_inserter(sink_));
591
+ }
592
+ }
593
+ else
594
+ {
595
+ if (val >= -32)
596
+ {
597
+ // negative fixnum stores 5-bit negative integer
598
+ binary::native_to_big(static_cast<int8_t>(val), std::back_inserter(sink_));
599
+ }
600
+ else if (val >= (std::numeric_limits<int8_t>::lowest)())
601
+ {
602
+ // int 8 stores a 8-bit signed integer
603
+ sink_.push_back(jsoncons::msgpack::msgpack_type::int8_type);
604
+ binary::native_to_big(static_cast<int8_t>(val),std::back_inserter(sink_));
605
+ }
606
+ else if (val >= (std::numeric_limits<int16_t>::lowest)())
607
+ {
608
+ // int 16 stores a 16-bit big-endian signed integer
609
+ sink_.push_back(jsoncons::msgpack::msgpack_type::int16_type);
610
+ binary::native_to_big(static_cast<int16_t>(val),std::back_inserter(sink_));
611
+ }
612
+ else if (val >= (std::numeric_limits<int32_t>::lowest)())
613
+ {
614
+ // int 32 stores a 32-bit big-endian signed integer
615
+ sink_.push_back(jsoncons::msgpack::msgpack_type::int32_type);
616
+ binary::native_to_big(static_cast<int32_t>(val),std::back_inserter(sink_));
617
+ }
618
+ else if (val >= (std::numeric_limits<int64_t>::lowest)())
619
+ {
620
+ // int 64 stores a 64-bit big-endian signed integer
621
+ sink_.push_back(jsoncons::msgpack::msgpack_type::int64_type);
622
+ binary::native_to_big(static_cast<int64_t>(val),std::back_inserter(sink_));
623
+ }
624
+ }
625
+ }
626
+ break;
627
+ }
628
+ end_value();
629
+ return true;
630
+ }
631
+
632
+ bool visit_uint64(uint64_t val,
633
+ semantic_tag tag,
634
+ const ser_context&,
635
+ std::error_code&) override
636
+ {
637
+ switch (tag)
638
+ {
639
+ case semantic_tag::epoch_second:
640
+ write_timestamp(static_cast<int64_t>(val), 0);
641
+ break;
642
+ case semantic_tag::epoch_milli:
643
+ {
644
+ if (val != 0)
645
+ {
646
+ auto dv = std::div(static_cast<int64_t>(val), static_cast<int64_t>(millis_in_second));
647
+ int64_t seconds = dv.quot;
648
+ int64_t nanoseconds = dv.rem*nanos_in_milli;
649
+ if (nanoseconds < 0)
650
+ {
651
+ nanoseconds = -nanoseconds;
652
+ }
653
+ write_timestamp(seconds, nanoseconds);
654
+ }
655
+ else
656
+ {
657
+ write_timestamp(0, 0);
658
+ }
659
+ break;
660
+ }
661
+ case semantic_tag::epoch_nano:
662
+ {
663
+ if (val != 0)
664
+ {
665
+ auto dv = std::div(static_cast<int64_t>(val), static_cast<int64_t>(nanos_in_second));
666
+ int64_t seconds = dv.quot;
667
+ int64_t nanoseconds = dv.rem;
668
+ if (nanoseconds < 0)
669
+ {
670
+ nanoseconds = -nanoseconds;
671
+ }
672
+ write_timestamp(seconds, nanoseconds);
673
+ }
674
+ else
675
+ {
676
+ write_timestamp(0, 0);
677
+ }
678
+ break;
679
+ }
680
+ default:
681
+ {
682
+ if (val <= static_cast<uint64_t>((std::numeric_limits<int8_t>::max)()))
683
+ {
684
+ // positive fixnum stores 7-bit positive integer
685
+ sink_.push_back(static_cast<uint8_t>(val));
686
+ }
687
+ else if (val <= (std::numeric_limits<uint8_t>::max)())
688
+ {
689
+ // uint 8 stores a 8-bit unsigned integer
690
+ sink_.push_back(jsoncons::msgpack::msgpack_type::uint8_type);
691
+ sink_.push_back(static_cast<uint8_t>(val));
692
+ }
693
+ else if (val <= (std::numeric_limits<uint16_t>::max)())
694
+ {
695
+ // uint 16 stores a 16-bit big-endian unsigned integer
696
+ sink_.push_back(jsoncons::msgpack::msgpack_type::uint16_type);
697
+ binary::native_to_big(static_cast<uint16_t>(val),std::back_inserter(sink_));
698
+ }
699
+ else if (val <= (std::numeric_limits<uint32_t>::max)())
700
+ {
701
+ // uint 32 stores a 32-bit big-endian unsigned integer
702
+ sink_.push_back(jsoncons::msgpack::msgpack_type::uint32_type);
703
+ binary::native_to_big(static_cast<uint32_t>(val),std::back_inserter(sink_));
704
+ }
705
+ else if (val <= (std::numeric_limits<uint64_t>::max)())
706
+ {
707
+ // uint 64 stores a 64-bit big-endian unsigned integer
708
+ sink_.push_back(jsoncons::msgpack::msgpack_type::uint64_type);
709
+ binary::native_to_big(static_cast<uint64_t>(val),std::back_inserter(sink_));
710
+ }
711
+ break;
712
+ }
713
+ }
714
+ end_value();
715
+ return true;
716
+ }
717
+
718
+ bool visit_bool(bool val, semantic_tag, const ser_context&, std::error_code&) override
719
+ {
720
+ // true and false
721
+ sink_.push_back(static_cast<uint8_t>(val ? jsoncons::msgpack::msgpack_type::true_type : jsoncons::msgpack::msgpack_type::false_type));
722
+
723
+ end_value();
724
+ return true;
725
+ }
726
+
727
+ void end_value()
728
+ {
729
+ if (!stack_.empty())
730
+ {
731
+ ++stack_.back().count_;
732
+ }
733
+ }
734
+ };
735
+
736
+ using msgpack_stream_encoder = basic_msgpack_encoder<jsoncons::binary_stream_sink>;
737
+ using msgpack_bytes_encoder = basic_msgpack_encoder<jsoncons::bytes_sink<std::vector<uint8_t>>>;
738
+
739
+ #if !defined(JSONCONS_NO_DEPRECATED)
740
+ JSONCONS_DEPRECATED_MSG("Instead, use msgpack_bytes_encoder") typedef msgpack_bytes_encoder msgpack_bytes_serializer;
741
+
742
+ template<class Sink=jsoncons::binary_stream_sink>
743
+ using basic_msgpack_serializer = basic_msgpack_encoder<Sink>;
744
+
745
+ JSONCONS_DEPRECATED_MSG("Instead, use msgpack_stream_encoder") typedef msgpack_stream_encoder msgpack_encoder;
746
+ JSONCONS_DEPRECATED_MSG("Instead, use msgpack_stream_encoder") typedef msgpack_stream_encoder msgpack_serializer;
747
+ JSONCONS_DEPRECATED_MSG("Instead, use msgpack_bytes_encoder") typedef msgpack_bytes_encoder msgpack_buffer_serializer;
748
+ #endif
749
+
750
+ } // namespace msgpack
751
+ } // namespace jsoncons
752
+
753
+ #endif