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