mirror of
https://github.com/simdjson/simdjson
synced 2026-06-08 17:27:07 +00:00
Fix fallback implementation
This commit is contained in:
@@ -9,15 +9,17 @@ namespace simdjson {
|
||||
namespace fallback {
|
||||
namespace stage1 {
|
||||
|
||||
#include "generic/stage1/find_next_document_index.h"
|
||||
|
||||
class structural_scanner {
|
||||
public:
|
||||
|
||||
really_inline structural_scanner(dom_parser_implementation &_parser, bool _streaming)
|
||||
really_inline structural_scanner(dom_parser_implementation &_parser, bool _partial)
|
||||
: buf{_parser.buf},
|
||||
next_structural_index{_parser.structural_indexes.get()},
|
||||
parser{_parser},
|
||||
len{static_cast<uint32_t>(_parser.len)},
|
||||
streaming{_streaming} {
|
||||
partial{_partial} {
|
||||
}
|
||||
|
||||
really_inline void add_structural() {
|
||||
@@ -41,7 +43,12 @@ really_inline void validate_utf8_character() {
|
||||
// 2-byte
|
||||
if ((buf[idx] & 0b00100000) == 0) {
|
||||
// missing continuation
|
||||
if (unlikely(idx+1 > len || !is_continuation(buf[idx+1]))) { error = UTF8_ERROR; idx++; return; }
|
||||
if (unlikely(idx+1 > len || !is_continuation(buf[idx+1]))) {
|
||||
if (idx+1 > len && partial) { idx = len; return; }
|
||||
error = UTF8_ERROR;
|
||||
idx++;
|
||||
return;
|
||||
}
|
||||
// overlong: 1100000_ 10______
|
||||
if (buf[idx] <= 0b11000001) { error = UTF8_ERROR; }
|
||||
idx += 2;
|
||||
@@ -51,7 +58,12 @@ really_inline void validate_utf8_character() {
|
||||
// 3-byte
|
||||
if ((buf[idx] & 0b00010000) == 0) {
|
||||
// missing continuation
|
||||
if (unlikely(idx+2 > len || !is_continuation(buf[idx+1]) || !is_continuation(buf[idx+2]))) { error = UTF8_ERROR; idx++; return; }
|
||||
if (unlikely(idx+2 > len || !is_continuation(buf[idx+1]) || !is_continuation(buf[idx+2]))) {
|
||||
if (idx+2 > len && partial) { idx = len; return; }
|
||||
error = UTF8_ERROR;
|
||||
idx++;
|
||||
return;
|
||||
}
|
||||
// overlong: 11100000 100_____ ________
|
||||
if (buf[idx] == 0b11100000 && buf[idx+1] <= 0b10011111) { error = UTF8_ERROR; }
|
||||
// surrogates: U+D800-U+DFFF 11101101 101_____
|
||||
@@ -62,7 +74,12 @@ really_inline void validate_utf8_character() {
|
||||
|
||||
// 4-byte
|
||||
// missing continuation
|
||||
if (unlikely(idx+3 > len || !is_continuation(buf[idx+1]) || !is_continuation(buf[idx+2]) || !is_continuation(buf[idx+3]))) { error = UTF8_ERROR; idx++; return; }
|
||||
if (unlikely(idx+3 > len || !is_continuation(buf[idx+1]) || !is_continuation(buf[idx+2]) || !is_continuation(buf[idx+3]))) {
|
||||
if (idx+2 > len && partial) { idx = len; return; }
|
||||
error = UTF8_ERROR;
|
||||
idx++;
|
||||
return;
|
||||
}
|
||||
// overlong: 11110000 1000____ ________ ________
|
||||
if (buf[idx] == 0b11110000 && buf[idx+1] <= 0b10001111) { error = UTF8_ERROR; }
|
||||
// too large: > U+10FFFF:
|
||||
@@ -87,7 +104,7 @@ really_inline void validate_string() {
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
if (idx >= len && !streaming) { error = UNCLOSED_STRING; }
|
||||
if (idx >= len && !partial) { error = UNCLOSED_STRING; }
|
||||
}
|
||||
|
||||
really_inline bool is_whitespace_or_operator(uint8_t c) {
|
||||
@@ -128,16 +145,26 @@ really_inline error_code scan() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (unlikely(next_structural_index == parser.structural_indexes.get())) {
|
||||
return EMPTY;
|
||||
}
|
||||
*next_structural_index = len;
|
||||
next_structural_index++;
|
||||
// We pad beyond.
|
||||
// https://github.com/simdjson/simdjson/issues/906
|
||||
next_structural_index[0] = len;
|
||||
next_structural_index[1] = 0;
|
||||
next_structural_index[1] = len;
|
||||
next_structural_index[2] = 0;
|
||||
parser.n_structural_indexes = uint32_t(next_structural_index - parser.structural_indexes.get());
|
||||
parser.next_structural_index = 0;
|
||||
|
||||
if (unlikely(parser.n_structural_indexes == 0)) {
|
||||
return EMPTY;
|
||||
}
|
||||
|
||||
if (partial) {
|
||||
auto new_structural_indexes = find_next_document_index(parser);
|
||||
if (new_structural_indexes == 0 && parser.n_structural_indexes > 0) {
|
||||
return CAPACITY; // If the buffer is partial but the document is incomplete, it's too big to parse.
|
||||
}
|
||||
parser.n_structural_indexes = new_structural_indexes;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -148,16 +175,16 @@ private:
|
||||
uint32_t len;
|
||||
uint32_t idx{0};
|
||||
error_code error{SUCCESS};
|
||||
bool streaming;
|
||||
bool partial;
|
||||
}; // structural_scanner
|
||||
|
||||
} // namespace stage1
|
||||
|
||||
|
||||
WARN_UNUSED error_code dom_parser_implementation::stage1(const uint8_t *_buf, size_t _len, bool streaming) noexcept {
|
||||
WARN_UNUSED error_code dom_parser_implementation::stage1(const uint8_t *_buf, size_t _len, bool partial) noexcept {
|
||||
this->buf = _buf;
|
||||
this->len = _len;
|
||||
stage1::structural_scanner scanner(*this, streaming);
|
||||
stage1::structural_scanner scanner(*this, partial);
|
||||
return scanner.scan();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user