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.
- checksums.yaml +7 -0
- data/ext/jsoncons/extconf.rb +43 -0
- data/ext/jsoncons/jsoncons.cpp +161 -0
- data/ext/jsoncons/jsoncons.h +10 -0
- data/jsoncons.gemspec +44 -0
- data/lib/jsoncons/jsoncons/examples/input/address-book.json +13 -0
- data/lib/jsoncons/jsoncons/examples/input/books.json +28 -0
- data/lib/jsoncons/jsoncons/examples/input/countries.json +7 -0
- data/lib/jsoncons/jsoncons/examples/input/employees.json +30 -0
- data/lib/jsoncons/jsoncons/examples/input/jsonschema/name.json +15 -0
- data/lib/jsoncons/jsoncons/examples/input/multiple-json-objects.json +3 -0
- data/lib/jsoncons/jsoncons/examples/input/sales.csv +6 -0
- data/lib/jsoncons/jsoncons/examples/input/store.json +28 -0
- data/lib/jsoncons/jsoncons/examples/input/tasks.csv +6 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/allocator_holder.hpp +38 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/basic_json.hpp +5905 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/bigint.hpp +1611 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/byte_string.hpp +820 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/config/binary_config.hpp +226 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/config/compiler_support.hpp +375 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/config/jsoncons_config.hpp +309 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/config/version.hpp +40 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/conv_error.hpp +218 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/decode_json.hpp +209 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/decode_traits.hpp +651 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/detail/endian.hpp +44 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/detail/grisu3.hpp +312 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/detail/optional.hpp +483 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/detail/parse_number.hpp +1133 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/detail/span.hpp +188 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/detail/string_view.hpp +537 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/detail/string_wrapper.hpp +370 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/detail/write_number.hpp +567 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/encode_json.hpp +315 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/encode_traits.hpp +378 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json.hpp +18 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_array.hpp +324 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_content_handler.hpp +12 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_cursor.hpp +448 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_decoder.hpp +420 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_encoder.hpp +1587 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_error.hpp +156 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_exception.hpp +241 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_filter.hpp +653 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_fwd.hpp +23 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_object.hpp +1772 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_options.hpp +862 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_parser.hpp +2900 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_reader.hpp +731 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_traits_macros.hpp +1072 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_traits_macros_deprecated.hpp +144 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_type.hpp +206 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_type_traits.hpp +1830 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_visitor.hpp +1560 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/json_visitor2.hpp +2079 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/pretty_print.hpp +89 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/ser_context.hpp +62 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/sink.hpp +289 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/source.hpp +777 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/source_adaptor.hpp +148 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/staj2_cursor.hpp +1189 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/staj_cursor.hpp +1254 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/staj_iterator.hpp +449 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/tag_type.hpp +245 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/text_source_adaptor.hpp +144 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/traits_extension.hpp +884 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/typed_array_view.hpp +250 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/unicode_traits.hpp +1330 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/uri.hpp +635 -0
- data/lib/jsoncons/jsoncons/include/jsoncons/value_converter.hpp +340 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson.hpp +23 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_cursor.hpp +320 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_decimal128.hpp +865 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_encoder.hpp +585 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_error.hpp +103 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_oid.hpp +245 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_options.hpp +75 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_parser.hpp +645 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_reader.hpp +92 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/bson_type.hpp +44 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/decode_bson.hpp +201 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/bson/encode_bson.hpp +144 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor.hpp +26 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_cursor.hpp +351 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_cursor2.hpp +265 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_detail.hpp +93 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_encoder.hpp +1766 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_error.hpp +105 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_options.hpp +113 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_parser.hpp +1942 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/cbor_reader.hpp +116 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/decode_cbor.hpp +203 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/cbor/encode_cbor.hpp +151 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv.hpp +17 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_cursor.hpp +358 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_encoder.hpp +954 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_error.hpp +85 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_options.hpp +973 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_parser.hpp +2099 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_reader.hpp +348 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/csv_serializer.hpp +12 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/decode_csv.hpp +208 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/csv/encode_csv.hpp +122 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jmespath/jmespath.hpp +5215 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jmespath/jmespath_error.hpp +215 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpatch/jsonpatch.hpp +579 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpatch/jsonpatch_error.hpp +121 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/expression.hpp +3329 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/flatten.hpp +432 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/json_location.hpp +445 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/json_query.hpp +115 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/jsonpath.hpp +13 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/jsonpath_error.hpp +240 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/jsonpath_expression.hpp +2612 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpath/jsonpath_selector.hpp +1322 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpointer/jsonpointer.hpp +1577 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonpointer/jsonpointer_error.hpp +119 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/format_validator.hpp +968 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/json_validator.hpp +120 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/jsonschema.hpp +13 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/jsonschema_error.hpp +105 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/jsonschema_version.hpp +18 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/keyword_validator.hpp +1745 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/keyword_validator_factory.hpp +556 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/schema_draft7.hpp +198 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/schema_location.hpp +200 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/schema_version.hpp +35 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/jsonschema/subschema.hpp +144 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/mergepatch/mergepatch.hpp +103 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/decode_msgpack.hpp +202 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/encode_msgpack.hpp +142 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack.hpp +24 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_cursor.hpp +343 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_cursor2.hpp +259 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_encoder.hpp +753 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_error.hpp +94 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_options.hpp +74 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_parser.hpp +748 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_reader.hpp +116 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/msgpack/msgpack_type.hpp +63 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/decode_ubjson.hpp +201 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/encode_ubjson.hpp +142 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson.hpp +23 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_cursor.hpp +307 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_encoder.hpp +502 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_error.hpp +100 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_options.hpp +87 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_parser.hpp +880 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_reader.hpp +92 -0
- data/lib/jsoncons/jsoncons/include/jsoncons_ext/ubjson/ubjson_type.hpp +43 -0
- data/lib/jsoncons/version.rb +5 -0
- data/lib/jsoncons.rb +33 -0
- data/test/jsoncons_test.rb +108 -0
- data/test/test_helper.rb +7 -0
- 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
|