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