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,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