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,777 @@
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_SOURCE_HPP
8
+ #define JSONCONS_SOURCE_HPP
9
+
10
+ #include <stdexcept>
11
+ #include <string>
12
+ #include <vector>
13
+ #include <istream>
14
+ #include <memory> // std::addressof
15
+ #include <cstring> // std::memcpy
16
+ #include <exception>
17
+ #include <iterator>
18
+ #include <type_traits> // std::enable_if
19
+ #include <jsoncons/config/jsoncons_config.hpp>
20
+ #include <jsoncons/byte_string.hpp> // jsoncons::byte_traits
21
+ #include <jsoncons/traits_extension.hpp>
22
+
23
+ namespace jsoncons {
24
+
25
+ template <class CharT>
26
+ class basic_null_istream : public std::basic_istream<CharT>
27
+ {
28
+ class null_buffer : public std::basic_streambuf<CharT>
29
+ {
30
+ null_buffer(const null_buffer&) = delete;
31
+ null_buffer& operator=(const null_buffer&) = delete;
32
+ public:
33
+ using typename std::basic_streambuf<CharT>::int_type;
34
+ using typename std::basic_streambuf<CharT>::traits_type;
35
+
36
+ null_buffer() = default;
37
+ null_buffer(null_buffer&&) = default;
38
+ null_buffer& operator=(null_buffer&&) = default;
39
+
40
+ int_type overflow( int_type ch = typename std::basic_streambuf<CharT>::traits_type::eof() ) override
41
+ {
42
+ return ch;
43
+ }
44
+ } nb_;
45
+ public:
46
+ basic_null_istream()
47
+ : std::basic_istream<CharT>(&nb_)
48
+ {
49
+ }
50
+
51
+ basic_null_istream(const null_buffer&) = delete;
52
+ basic_null_istream& operator=(const null_buffer&) = delete;
53
+ basic_null_istream(basic_null_istream&&) noexcept
54
+ : std::basic_istream<CharT>(&nb_)
55
+ {
56
+ }
57
+ basic_null_istream& operator=(basic_null_istream&&) noexcept
58
+ {
59
+ return *this;
60
+ }
61
+ };
62
+
63
+ template <class CharT>
64
+ struct char_result
65
+ {
66
+ CharT value;
67
+ bool eof;
68
+ };
69
+
70
+ // text sources
71
+
72
+ template <class CharT>
73
+ class stream_source
74
+ {
75
+ static constexpr std::size_t default_max_buffer_size = 16384;
76
+ public:
77
+ using value_type = CharT;
78
+ private:
79
+ using char_type = typename std::conditional<sizeof(CharT) == sizeof(char),char,CharT>::type;
80
+ basic_null_istream<char_type> null_is_;
81
+ std::basic_istream<char_type>* stream_ptr_;
82
+ std::basic_streambuf<char_type>* sbuf_;
83
+ std::size_t position_;
84
+ std::vector<value_type> buffer_;
85
+ const value_type* buffer_data_;
86
+ std::size_t buffer_length_;
87
+
88
+ // Noncopyable
89
+ stream_source(const stream_source&) = delete;
90
+ stream_source& operator=(const stream_source&) = delete;
91
+ public:
92
+ stream_source()
93
+ : stream_ptr_(&null_is_), sbuf_(null_is_.rdbuf()), position_(0),
94
+ buffer_(1), buffer_data_(buffer_.data()), buffer_length_(0)
95
+ {
96
+ }
97
+
98
+ stream_source(std::basic_istream<char_type>& is, std::size_t buf_size = default_max_buffer_size)
99
+ : stream_ptr_(std::addressof(is)), sbuf_(is.rdbuf()), position_(0),
100
+ buffer_(buf_size), buffer_data_(buffer_.data()), buffer_length_(0)
101
+ {
102
+ }
103
+
104
+ stream_source(stream_source&& other) noexcept
105
+ : stream_ptr_(&null_is_), sbuf_(null_is_.rdbuf()), position_(0),
106
+ buffer_(), buffer_data_(buffer_.data()), buffer_length_(0)
107
+ {
108
+ if (other.stream_ptr_ != &other.null_is_)
109
+ {
110
+ stream_ptr_ = other.stream_ptr_;
111
+ sbuf_ = other.sbuf_;
112
+ position_ = other.position_;
113
+ buffer_ = std::move(other.buffer_);
114
+ buffer_data_ = buffer_.data() + (other.buffer_data_ - other.buffer_.data());
115
+ buffer_length_ = other.buffer_length_;
116
+ other = stream_source();
117
+ }
118
+ }
119
+
120
+ ~stream_source()
121
+ {
122
+ }
123
+
124
+ stream_source& operator=(stream_source&& other) noexcept
125
+ {
126
+ if (other.stream_ptr_ != &other.null_is_)
127
+ {
128
+ stream_ptr_ = other.stream_ptr_;
129
+ sbuf_ = other.sbuf_;
130
+ position_ = other.position_;
131
+ buffer_ = std::move(other.buffer_);
132
+ buffer_data_ = buffer_.data() + (other.buffer_data_ - other.buffer_.data());
133
+ buffer_length_ = other.buffer_length_;
134
+ other = stream_source();
135
+ }
136
+ else
137
+ {
138
+ stream_ptr_ = &null_is_;
139
+ sbuf_ = null_is_.rdbuf();
140
+ position_ = 0;
141
+ buffer_data_ = buffer_.data();
142
+ buffer_length_ = 0;
143
+ }
144
+ return *this;
145
+ }
146
+
147
+ bool eof() const
148
+ {
149
+ return buffer_length_ == 0 && stream_ptr_->eof();
150
+ }
151
+
152
+ bool is_error() const
153
+ {
154
+ return stream_ptr_->bad();
155
+ }
156
+
157
+ std::size_t position() const
158
+ {
159
+ return position_;
160
+ }
161
+
162
+ void ignore(std::size_t length)
163
+ {
164
+ std::size_t len = 0;
165
+ if (buffer_length_ > 0)
166
+ {
167
+ len = (std::min)(buffer_length_, length);
168
+ position_ += len;
169
+ buffer_data_ += len;
170
+ buffer_length_ -= len;
171
+ }
172
+ while (length - len > 0)
173
+ {
174
+ fill_buffer();
175
+ if (buffer_length_ == 0)
176
+ {
177
+ break;
178
+ }
179
+ std::size_t len2 = (std::min)(buffer_length_, length-len);
180
+ position_ += len2;
181
+ buffer_data_ += len2;
182
+ buffer_length_ -= len2;
183
+ len += len2;
184
+ }
185
+ }
186
+
187
+ char_result<value_type> peek()
188
+ {
189
+ if (buffer_length_ == 0)
190
+ {
191
+ fill_buffer();
192
+ }
193
+ if (buffer_length_ > 0)
194
+ {
195
+ value_type c = *buffer_data_;
196
+ return char_result<value_type>{c, false};
197
+ }
198
+ else
199
+ {
200
+ return char_result<value_type>{0, true};
201
+ }
202
+ }
203
+
204
+ span<const value_type> read_buffer()
205
+ {
206
+ if (buffer_length_ == 0)
207
+ {
208
+ fill_buffer();
209
+ }
210
+ const value_type* data = buffer_data_;
211
+ std::size_t length = buffer_length_;
212
+ buffer_data_ += buffer_length_;
213
+ position_ += buffer_length_;
214
+ buffer_length_ = 0;
215
+
216
+ return span<const value_type>(data, length);
217
+ }
218
+
219
+ std::size_t read(value_type* p, std::size_t length)
220
+ {
221
+ std::size_t len = 0;
222
+ if (buffer_length_ > 0)
223
+ {
224
+ len = (std::min)(buffer_length_, length);
225
+ std::memcpy(p, buffer_data_, len*sizeof(value_type));
226
+ buffer_data_ += len;
227
+ buffer_length_ -= len;
228
+ position_ += len;
229
+ }
230
+ if (length - len == 0)
231
+ {
232
+ return len;
233
+ }
234
+ else if (length - len < buffer_.size())
235
+ {
236
+ fill_buffer();
237
+ if (buffer_length_ > 0)
238
+ {
239
+ std::size_t len2 = (std::min)(buffer_length_, length-len);
240
+ std::memcpy(p+len, buffer_data_, len2*sizeof(value_type));
241
+ buffer_data_ += len2;
242
+ buffer_length_ -= len2;
243
+ position_ += len2;
244
+ len += len2;
245
+ }
246
+ return len;
247
+ }
248
+ else
249
+ {
250
+ if (stream_ptr_->eof())
251
+ {
252
+ buffer_length_ = 0;
253
+ return 0;
254
+ }
255
+ JSONCONS_TRY
256
+ {
257
+ std::streamsize count = sbuf_->sgetn(reinterpret_cast<char_type*>(p+len), length-len);
258
+ std::size_t len2 = static_cast<std::size_t>(count);
259
+ if (len2 < length-len)
260
+ {
261
+ stream_ptr_->clear(stream_ptr_->rdstate() | std::ios::eofbit);
262
+ }
263
+ len += len2;
264
+ position_ += len2;
265
+ return len;
266
+ }
267
+ JSONCONS_CATCH(const std::exception&)
268
+ {
269
+ stream_ptr_->clear(stream_ptr_->rdstate() | std::ios::badbit | std::ios::eofbit);
270
+ return 0;
271
+ }
272
+ }
273
+ }
274
+ private:
275
+ void fill_buffer()
276
+ {
277
+ if (stream_ptr_->eof())
278
+ {
279
+ buffer_length_ = 0;
280
+ return;
281
+ }
282
+
283
+ buffer_data_ = buffer_.data();
284
+ JSONCONS_TRY
285
+ {
286
+ std::streamsize count = sbuf_->sgetn(reinterpret_cast<char_type*>(buffer_.data()), buffer_.size());
287
+ buffer_length_ = static_cast<std::size_t>(count);
288
+
289
+ if (buffer_length_ < buffer_.size())
290
+ {
291
+ stream_ptr_->clear(stream_ptr_->rdstate() | std::ios::eofbit);
292
+ }
293
+ }
294
+ JSONCONS_CATCH(const std::exception&)
295
+ {
296
+ stream_ptr_->clear(stream_ptr_->rdstate() | std::ios::badbit | std::ios::eofbit);
297
+ buffer_length_ = 0;
298
+ }
299
+ }
300
+ };
301
+
302
+ // string_source
303
+
304
+ template <class CharT>
305
+ class string_source
306
+ {
307
+ public:
308
+ using value_type = CharT;
309
+ using string_view_type = jsoncons::basic_string_view<value_type>;
310
+ private:
311
+ const value_type* data_;
312
+ const value_type* current_;
313
+ const value_type* end_;
314
+
315
+ // Noncopyable
316
+ string_source(const string_source&) = delete;
317
+ string_source& operator=(const string_source&) = delete;
318
+ public:
319
+ string_source()
320
+ : data_(nullptr), current_(nullptr), end_(nullptr)
321
+ {
322
+ }
323
+
324
+ template <class Sourceable>
325
+ string_source(const Sourceable& s,
326
+ typename std::enable_if<traits_extension::is_sequence_of<Sourceable,value_type>::value>::type* = 0)
327
+ : data_(s.data()), current_(s.data()), end_(s.data()+s.size())
328
+ {
329
+ }
330
+
331
+ string_source(const value_type* data)
332
+ : data_(data), current_(data), end_(data+std::char_traits<value_type>::length(data))
333
+ {
334
+ }
335
+
336
+ string_source(string_source&& val) = default;
337
+
338
+ string_source& operator=(string_source&& val) = default;
339
+
340
+ bool eof() const
341
+ {
342
+ return current_ == end_;
343
+ }
344
+
345
+ bool is_error() const
346
+ {
347
+ return false;
348
+ }
349
+
350
+ std::size_t position() const
351
+ {
352
+ return (current_ - data_)/sizeof(value_type);
353
+ }
354
+
355
+ void ignore(std::size_t count)
356
+ {
357
+ std::size_t len;
358
+ if ((std::size_t)(end_ - current_) < count)
359
+ {
360
+ len = end_ - current_;
361
+ }
362
+ else
363
+ {
364
+ len = count;
365
+ }
366
+ current_ += len;
367
+ }
368
+
369
+ char_result<value_type> peek()
370
+ {
371
+ return current_ < end_ ? char_result<value_type>{*current_, false} : char_result<value_type>{0, true};
372
+ }
373
+
374
+ span<const value_type> read_buffer()
375
+ {
376
+ const value_type* data = current_;
377
+ std::size_t length = end_ - current_;
378
+ current_ = end_;
379
+
380
+ return span<const value_type>(data, length);
381
+ }
382
+
383
+ std::size_t read(value_type* p, std::size_t length)
384
+ {
385
+ std::size_t len;
386
+ if ((std::size_t)(end_ - current_) < length)
387
+ {
388
+ len = end_ - current_;
389
+ }
390
+ else
391
+ {
392
+ len = length;
393
+ }
394
+ std::memcpy(p, current_, len*sizeof(value_type));
395
+ current_ += len;
396
+ return len;
397
+ }
398
+ };
399
+
400
+ // iterator source
401
+
402
+ template <class IteratorT>
403
+ class iterator_source
404
+ {
405
+ public:
406
+ using value_type = typename std::iterator_traits<IteratorT>::value_type;
407
+ private:
408
+ static constexpr std::size_t default_max_buffer_size = 16384;
409
+
410
+ IteratorT current_;
411
+ IteratorT end_;
412
+ std::size_t position_;
413
+ std::vector<value_type> buffer_;
414
+ std::size_t buffer_length_;
415
+
416
+ using difference_type = typename std::iterator_traits<IteratorT>::difference_type;
417
+ using iterator_category = typename std::iterator_traits<IteratorT>::iterator_category;
418
+
419
+ // Noncopyable
420
+ iterator_source(const iterator_source&) = delete;
421
+ iterator_source& operator=(const iterator_source&) = delete;
422
+ public:
423
+
424
+ iterator_source(const IteratorT& first, const IteratorT& last, std::size_t buf_size = default_max_buffer_size)
425
+ : current_(first), end_(last), position_(0), buffer_(buf_size), buffer_length_(0)
426
+ {
427
+ }
428
+
429
+ iterator_source(iterator_source&& other) = default;
430
+
431
+ iterator_source& operator=(iterator_source&& other) = default;
432
+
433
+ bool eof() const
434
+ {
435
+ return !(current_ != end_);
436
+ }
437
+
438
+ bool is_error() const
439
+ {
440
+ return false;
441
+ }
442
+
443
+ std::size_t position() const
444
+ {
445
+ return position_;
446
+ }
447
+
448
+ void ignore(std::size_t count)
449
+ {
450
+ while (count-- > 0 && current_ != end_)
451
+ {
452
+ ++position_;
453
+ ++current_;
454
+ }
455
+ }
456
+
457
+ char_result<value_type> peek()
458
+ {
459
+ return current_ != end_ ? char_result<value_type>{*current_, false} : char_result<value_type>{0, true};
460
+ }
461
+
462
+ span<const value_type> read_buffer()
463
+ {
464
+ if (buffer_length_ == 0)
465
+ {
466
+ buffer_length_ = read(buffer_.data(), buffer_.size());
467
+ }
468
+ std::size_t length = buffer_length_;
469
+ buffer_length_ = 0;
470
+
471
+ return span<const value_type>(buffer_.data(), length);
472
+ }
473
+
474
+ template <class Category = iterator_category>
475
+ typename std::enable_if<std::is_same<Category,std::random_access_iterator_tag>::value, std::size_t>::type
476
+ read(value_type* data, std::size_t length)
477
+ {
478
+ std::size_t count = (std::min)(length, static_cast<std::size_t>(std::distance(current_, end_)));
479
+
480
+ JSONCONS_COPY(current_, current_ + count, data);
481
+ current_ += count;
482
+ position_ += count;
483
+
484
+ return count;
485
+ }
486
+
487
+ template <class Category = iterator_category>
488
+ typename std::enable_if<!std::is_same<Category,std::random_access_iterator_tag>::value, std::size_t>::type
489
+ read(value_type* data, std::size_t length)
490
+ {
491
+ value_type* p = data;
492
+ value_type* pend = data + length;
493
+
494
+ while (p < pend && current_ != end_)
495
+ {
496
+ *p = static_cast<value_type>(*current_);
497
+ ++p;
498
+ ++current_;
499
+ }
500
+
501
+ position_ += (p - data);
502
+
503
+ return p - data;
504
+ }
505
+ };
506
+
507
+ // binary sources
508
+
509
+ using binary_stream_source = stream_source<uint8_t>;
510
+
511
+ class bytes_source
512
+ {
513
+ public:
514
+ typedef uint8_t value_type;
515
+ private:
516
+ const value_type* data_;
517
+ const value_type* current_;
518
+ const value_type* end_;
519
+
520
+ // Noncopyable
521
+ bytes_source(const bytes_source&) = delete;
522
+ bytes_source& operator=(const bytes_source&) = delete;
523
+ public:
524
+ bytes_source()
525
+ : data_(nullptr), current_(nullptr), end_(nullptr)
526
+ {
527
+ }
528
+
529
+ template <class Sourceable>
530
+ bytes_source(const Sourceable& source,
531
+ typename std::enable_if<traits_extension::is_byte_sequence<Sourceable>::value,int>::type = 0)
532
+ : data_(reinterpret_cast<const value_type*>(source.data())),
533
+ current_(data_),
534
+ end_(data_+source.size())
535
+ {
536
+ }
537
+
538
+ bytes_source(bytes_source&&) = default;
539
+
540
+ bytes_source& operator=(bytes_source&&) = default;
541
+
542
+ bool eof() const
543
+ {
544
+ return current_ == end_;
545
+ }
546
+
547
+ bool is_error() const
548
+ {
549
+ return false;
550
+ }
551
+
552
+ std::size_t position() const
553
+ {
554
+ return current_ - data_;
555
+ }
556
+
557
+ void ignore(std::size_t count)
558
+ {
559
+ std::size_t len;
560
+ if ((std::size_t)(end_ - current_) < count)
561
+ {
562
+ len = end_ - current_;
563
+ }
564
+ else
565
+ {
566
+ len = count;
567
+ }
568
+ current_ += len;
569
+ }
570
+
571
+ char_result<value_type> peek()
572
+ {
573
+ return current_ < end_ ? char_result<value_type>{*current_, false} : char_result<value_type>{0, true};
574
+ }
575
+
576
+ span<const value_type> read_buffer()
577
+ {
578
+ const value_type* data = current_;
579
+ std::size_t length = end_ - current_;
580
+ current_ = end_;
581
+
582
+ return span<const value_type>(data, length);
583
+ }
584
+
585
+ std::size_t read(value_type* p, std::size_t length)
586
+ {
587
+ std::size_t len;
588
+ if ((std::size_t)(end_ - current_) < length)
589
+ {
590
+ len = end_ - current_;
591
+ }
592
+ else
593
+ {
594
+ len = length;
595
+ }
596
+ std::memcpy(p, current_, len*sizeof(value_type));
597
+ current_ += len;
598
+ return len;
599
+ }
600
+ };
601
+
602
+ // binary_iterator source
603
+
604
+ template <class IteratorT>
605
+ class binary_iterator_source
606
+ {
607
+ public:
608
+ using value_type = uint8_t;
609
+ private:
610
+ static constexpr std::size_t default_max_buffer_size = 16384;
611
+
612
+ IteratorT current_;
613
+ IteratorT end_;
614
+ std::size_t position_;
615
+ std::vector<value_type> buffer_;
616
+ std::size_t buffer_length_;
617
+
618
+ using difference_type = typename std::iterator_traits<IteratorT>::difference_type;
619
+ using iterator_category = typename std::iterator_traits<IteratorT>::iterator_category;
620
+
621
+ // Noncopyable
622
+ binary_iterator_source(const binary_iterator_source&) = delete;
623
+ binary_iterator_source& operator=(const binary_iterator_source&) = delete;
624
+ public:
625
+ binary_iterator_source(const IteratorT& first, const IteratorT& last, std::size_t buf_size = default_max_buffer_size)
626
+ : current_(first), end_(last), position_(0), buffer_(buf_size), buffer_length_(0)
627
+ {
628
+ }
629
+
630
+ binary_iterator_source(binary_iterator_source&& other) = default;
631
+
632
+ binary_iterator_source& operator=(binary_iterator_source&& other) = default;
633
+
634
+ bool eof() const
635
+ {
636
+ return !(current_ != end_);
637
+ }
638
+
639
+ bool is_error() const
640
+ {
641
+ return false;
642
+ }
643
+
644
+ std::size_t position() const
645
+ {
646
+ return position_;
647
+ }
648
+
649
+ void ignore(std::size_t count)
650
+ {
651
+ while (count-- > 0 && current_ != end_)
652
+ {
653
+ ++position_;
654
+ ++current_;
655
+ }
656
+ }
657
+
658
+ char_result<value_type> peek()
659
+ {
660
+ return current_ != end_ ? char_result<value_type>{static_cast<value_type>(*current_), false} : char_result<value_type>{0, true};
661
+ }
662
+
663
+ span<const value_type> read_buffer()
664
+ {
665
+ if (buffer_length_ == 0)
666
+ {
667
+ buffer_length_ = read(buffer_.data(), buffer_.size());
668
+ }
669
+ std::size_t length = buffer_length_;
670
+ buffer_length_ = 0;
671
+
672
+ return span<const value_type>(buffer_.data(), length);
673
+ }
674
+
675
+ template <class Category = iterator_category>
676
+ typename std::enable_if<std::is_same<Category,std::random_access_iterator_tag>::value, std::size_t>::type
677
+ read(value_type* data, std::size_t length)
678
+ {
679
+ std::size_t count = (std::min)(length, static_cast<std::size_t>(std::distance(current_, end_)));
680
+ JSONCONS_COPY(current_, current_ + count, data);
681
+ current_ += count;
682
+ position_ += count;
683
+
684
+ return count;
685
+ }
686
+
687
+ template <class Category = iterator_category>
688
+ typename std::enable_if<!std::is_same<Category,std::random_access_iterator_tag>::value, std::size_t>::type
689
+ read(value_type* data, std::size_t length)
690
+ {
691
+ value_type* p = data;
692
+ value_type* pend = data + length;
693
+
694
+ while (p < pend && current_ != end_)
695
+ {
696
+ *p = static_cast<value_type>(*current_);
697
+ ++p;
698
+ ++current_;
699
+ }
700
+
701
+ position_ += (p - data);
702
+
703
+ return p - data;
704
+ }
705
+ };
706
+
707
+ template <class Source>
708
+ struct source_reader
709
+ {
710
+ using value_type = typename Source::value_type;
711
+ static constexpr std::size_t max_buffer_length = 16384;
712
+
713
+ template <class Container>
714
+ static
715
+ typename std::enable_if<std::is_convertible<value_type,typename Container::value_type>::value &&
716
+ traits_extension::has_reserve<Container>::value &&
717
+ traits_extension::has_data_exact<value_type*,Container>::value
718
+ , std::size_t>::type
719
+ read(Source& source, Container& v, std::size_t length)
720
+ {
721
+ std::size_t unread = length;
722
+
723
+ std::size_t n = (std::min)(max_buffer_length, unread);
724
+ while (n > 0 && !source.eof())
725
+ {
726
+ std::size_t offset = v.size();
727
+ v.resize(v.size()+n);
728
+ std::size_t actual = source.read(v.data()+offset, n);
729
+ unread -= actual;
730
+ n = (std::min)(max_buffer_length, unread);
731
+ }
732
+
733
+ return length - unread;
734
+ }
735
+
736
+ template <class Container>
737
+ static
738
+ typename std::enable_if<std::is_convertible<value_type,typename Container::value_type>::value &&
739
+ traits_extension::has_reserve<Container>::value &&
740
+ !traits_extension::has_data_exact<value_type*, Container>::value
741
+ , std::size_t>::type
742
+ read(Source& source, Container& v, std::size_t length)
743
+ {
744
+ std::size_t unread = length;
745
+
746
+ std::size_t n = (std::min)(max_buffer_length, unread);
747
+ while (n > 0 && !source.eof())
748
+ {
749
+ v.reserve(v.size()+n);
750
+ std::size_t actual = 0;
751
+ while (actual < n)
752
+ {
753
+ typename Source::value_type c;
754
+ if (source.read(&c,1) != 1)
755
+ {
756
+ break;
757
+ }
758
+ v.push_back(c);
759
+ ++actual;
760
+ }
761
+ unread -= actual;
762
+ n = (std::min)(max_buffer_length, unread);
763
+ }
764
+
765
+ return length - unread;
766
+ }
767
+ };
768
+ template <class Source>
769
+ constexpr std::size_t source_reader<Source>::max_buffer_length;
770
+
771
+ #if !defined(JSONCONS_NO_DEPRECATED)
772
+ using bin_stream_source = binary_stream_source;
773
+ #endif
774
+
775
+ } // namespace jsoncons
776
+
777
+ #endif