1 | namespace simdjson { |
2 | namespace SIMDJSON_IMPLEMENTATION { |
3 | namespace ondemand { |
4 | |
5 | simdjson_inline parser::parser(size_t max_capacity) noexcept |
6 | : _max_capacity{max_capacity} { |
7 | } |
8 | |
9 | simdjson_warn_unused simdjson_inline error_code parser::allocate(size_t new_capacity, size_t new_max_depth) noexcept { |
10 | if (new_capacity > max_capacity()) { return CAPACITY; } |
11 | if (string_buf && new_capacity == capacity() && new_max_depth == max_depth()) { return SUCCESS; } |
12 | |
13 | // string_capacity copied from document::allocate |
14 | _capacity = 0; |
15 | size_t string_capacity = SIMDJSON_ROUNDUP_N(5 * new_capacity / 3 + SIMDJSON_PADDING, 64); |
16 | string_buf.reset(p: new (std::nothrow) uint8_t[string_capacity]); |
17 | #if SIMDJSON_DEVELOPMENT_CHECKS |
18 | start_positions.reset(new (std::nothrow) token_position[new_max_depth]); |
19 | #endif |
20 | if (implementation) { |
21 | SIMDJSON_TRY( implementation->set_capacity(new_capacity) ); |
22 | SIMDJSON_TRY( implementation->set_max_depth(new_max_depth) ); |
23 | } else { |
24 | SIMDJSON_TRY( simdjson::get_active_implementation()->create_dom_parser_implementation(new_capacity, new_max_depth, implementation) ); |
25 | } |
26 | _capacity = new_capacity; |
27 | _max_depth = new_max_depth; |
28 | return SUCCESS; |
29 | } |
30 | |
31 | simdjson_warn_unused simdjson_inline simdjson_result<document> parser::iterate(padded_string_view json) & noexcept { |
32 | if (json.padding() < SIMDJSON_PADDING) { return INSUFFICIENT_PADDING; } |
33 | |
34 | // Allocate if needed |
35 | if (capacity() < json.length() || !string_buf) { |
36 | SIMDJSON_TRY( allocate(json.length(), max_depth()) ); |
37 | } |
38 | |
39 | // Run stage 1. |
40 | SIMDJSON_TRY( implementation->stage1(reinterpret_cast<const uint8_t *>(json.data()), json.length(), stage1_mode::regular) ); |
41 | return document::start(iter: { reinterpret_cast<const uint8_t *>(json.data()), this }); |
42 | } |
43 | |
44 | simdjson_warn_unused simdjson_inline simdjson_result<document> parser::iterate(const char *json, size_t len, size_t allocated) & noexcept { |
45 | return iterate(json: padded_string_view(json, len, allocated)); |
46 | } |
47 | |
48 | simdjson_warn_unused simdjson_inline simdjson_result<document> parser::iterate(const uint8_t *json, size_t len, size_t allocated) & noexcept { |
49 | return iterate(json: padded_string_view(json, len, allocated)); |
50 | } |
51 | |
52 | simdjson_warn_unused simdjson_inline simdjson_result<document> parser::iterate(std::string_view json, size_t allocated) & noexcept { |
53 | return iterate(json: padded_string_view(json, allocated)); |
54 | } |
55 | |
56 | simdjson_warn_unused simdjson_inline simdjson_result<document> parser::iterate(const std::string &json) & noexcept { |
57 | return iterate(json: padded_string_view(json)); |
58 | } |
59 | |
60 | simdjson_warn_unused simdjson_inline simdjson_result<document> parser::iterate(const simdjson_result<padded_string_view> &result) & noexcept { |
61 | // We don't presently have a way to temporarily get a const T& from a simdjson_result<T> without throwing an exception |
62 | SIMDJSON_TRY( result.error() ); |
63 | padded_string_view json = result.value_unsafe(); |
64 | return iterate(json); |
65 | } |
66 | |
67 | simdjson_warn_unused simdjson_inline simdjson_result<document> parser::iterate(const simdjson_result<padded_string> &result) & noexcept { |
68 | // We don't presently have a way to temporarily get a const T& from a simdjson_result<T> without throwing an exception |
69 | SIMDJSON_TRY( result.error() ); |
70 | const padded_string &json = result.value_unsafe(); |
71 | return iterate(json); |
72 | } |
73 | |
74 | simdjson_warn_unused simdjson_inline simdjson_result<json_iterator> parser::iterate_raw(padded_string_view json) & noexcept { |
75 | if (json.padding() < SIMDJSON_PADDING) { return INSUFFICIENT_PADDING; } |
76 | |
77 | // Allocate if needed |
78 | if (capacity() < json.length()) { |
79 | SIMDJSON_TRY( allocate(json.length(), max_depth()) ); |
80 | } |
81 | |
82 | // Run stage 1. |
83 | SIMDJSON_TRY( implementation->stage1(reinterpret_cast<const uint8_t *>(json.data()), json.length(), stage1_mode::regular) ); |
84 | return json_iterator(reinterpret_cast<const uint8_t *>(json.data()), this); |
85 | } |
86 | |
87 | inline simdjson_result<document_stream> parser::iterate_many(const uint8_t *buf, size_t len, size_t batch_size) noexcept { |
88 | if(batch_size < MINIMAL_BATCH_SIZE) { batch_size = MINIMAL_BATCH_SIZE; } |
89 | return document_stream(*this, buf, len, batch_size); |
90 | } |
91 | inline simdjson_result<document_stream> parser::iterate_many(const char *buf, size_t len, size_t batch_size) noexcept { |
92 | return iterate_many(buf: reinterpret_cast<const uint8_t *>(buf), len, batch_size); |
93 | } |
94 | inline simdjson_result<document_stream> parser::iterate_many(const std::string &s, size_t batch_size) noexcept { |
95 | return iterate_many(buf: s.data(), len: s.length(), batch_size); |
96 | } |
97 | inline simdjson_result<document_stream> parser::iterate_many(const padded_string &s, size_t batch_size) noexcept { |
98 | return iterate_many(buf: s.data(), len: s.length(), batch_size); |
99 | } |
100 | |
101 | simdjson_inline size_t parser::capacity() const noexcept { |
102 | return _capacity; |
103 | } |
104 | simdjson_inline size_t parser::max_capacity() const noexcept { |
105 | return _max_capacity; |
106 | } |
107 | simdjson_inline size_t parser::max_depth() const noexcept { |
108 | return _max_depth; |
109 | } |
110 | |
111 | simdjson_inline void parser::set_max_capacity(size_t max_capacity) noexcept { |
112 | if(max_capacity < dom::MINIMAL_DOCUMENT_CAPACITY) { |
113 | _max_capacity = max_capacity; |
114 | } else { |
115 | _max_capacity = dom::MINIMAL_DOCUMENT_CAPACITY; |
116 | } |
117 | } |
118 | |
119 | simdjson_inline simdjson_warn_unused simdjson_result<std::string_view> parser::unescape(raw_json_string in, uint8_t *&dst, bool allow_replacement) const noexcept { |
120 | uint8_t *end = implementation->parse_string(src: in.buf, dst, allow_replacement); |
121 | if (!end) { return STRING_ERROR; } |
122 | std::string_view result(reinterpret_cast<const char *>(dst), end-dst); |
123 | dst = end; |
124 | return result; |
125 | } |
126 | |
127 | simdjson_inline simdjson_warn_unused simdjson_result<std::string_view> parser::unescape_wobbly(raw_json_string in, uint8_t *&dst) const noexcept { |
128 | uint8_t *end = implementation->parse_wobbly_string(src: in.buf, dst); |
129 | if (!end) { return STRING_ERROR; } |
130 | std::string_view result(reinterpret_cast<const char *>(dst), end-dst); |
131 | dst = end; |
132 | return result; |
133 | } |
134 | |
135 | } // namespace ondemand |
136 | } // namespace SIMDJSON_IMPLEMENTATION |
137 | } // namespace simdjson |
138 | |
139 | namespace simdjson { |
140 | |
141 | simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::parser>::simdjson_result(SIMDJSON_IMPLEMENTATION::ondemand::parser &&value) noexcept |
142 | : implementation_simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::parser>(std::forward<SIMDJSON_IMPLEMENTATION::ondemand::parser>(t&: value)) {} |
143 | simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::parser>::simdjson_result(error_code error) noexcept |
144 | : implementation_simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::parser>(error) {} |
145 | |
146 | } // namespace simdjson |
147 | |