1 #ifndef SIMDJSON_GENERIC_ONDEMAND_PARSER_INL_H
3 #ifndef SIMDJSON_CONDITIONAL_INCLUDE
4 #define SIMDJSON_GENERIC_ONDEMAND_PARSER_INL_H
5 #include "simdjson/padded_string.h"
6 #include "simdjson/padded_string_view.h"
7 #include "simdjson/implementation.h"
8 #include "simdjson/internal/dom_parser_implementation.h"
9 #include "simdjson/dom/base.h"
10 #include "simdjson/generic/ondemand/base.h"
11 #include "simdjson/generic/ondemand/document_stream.h"
12 #include "simdjson/generic/ondemand/parser.h"
13 #include "simdjson/generic/ondemand/raw_json_string.h"
17 namespace SIMDJSON_IMPLEMENTATION {
21 : _max_capacity{max_capacity} {
25 if (new_capacity > max_capacity()) {
return CAPACITY; }
26 if (string_buf && new_capacity == capacity() && new_max_depth == max_depth()) {
return SUCCESS; }
30 size_t string_capacity = SIMDJSON_ROUNDUP_N(5 * new_capacity / 3 +
SIMDJSON_PADDING, 64);
31 string_buf.reset(
new (std::nothrow) uint8_t[string_capacity]);
32 #if SIMDJSON_DEVELOPMENT_CHECKS
33 start_positions.reset(
new (std::nothrow) token_position[new_max_depth]);
41 _capacity = new_capacity;
42 _max_depth = new_max_depth;
45 #if SIMDJSON_DEVELOPMENT_CHECKS
46 simdjson_inline simdjson_warn_unused
bool parser::string_buffer_overflow(
const uint8_t *string_buf_loc)
const noexcept {
47 return (string_buf_loc < string_buf.get()) || (size_t(string_buf_loc - string_buf.get()) >= capacity());
54 json.remove_utf8_bom();
57 if (capacity() < json.length() || !string_buf) {
58 SIMDJSON_TRY( allocate(json.length(), max_depth()) );
62 SIMDJSON_TRY(
implementation->stage1(
reinterpret_cast<const uint8_t *
>(json.data()), json.length(), stage1_mode::regular) );
63 return document::start({
reinterpret_cast<const uint8_t *
>(json.data()),
this });
66 #ifdef SIMDJSON_EXPERIMENTAL_ALLOW_INCOMPLETE_JSON
70 json.remove_utf8_bom();
73 if (capacity() < json.length() || !string_buf) {
74 SIMDJSON_TRY( allocate(json.length(), max_depth()) );
83 return document::start({
reinterpret_cast<const uint8_t *
>(json.data()),
this,
true });
87 simdjson_warn_unused simdjson_inline simdjson_result<document>
parser::iterate(
const char *json,
size_t len,
size_t allocated) & noexcept {
88 return iterate(padded_string_view(json, len, allocated));
91 simdjson_warn_unused simdjson_inline simdjson_result<document>
parser::iterate(
const uint8_t *json,
size_t len,
size_t allocated) & noexcept {
92 return iterate(padded_string_view(json, len, allocated));
95 simdjson_warn_unused simdjson_inline simdjson_result<document>
parser::iterate(std::string_view json,
size_t allocated) & noexcept {
96 return iterate(padded_string_view(json, allocated));
99 simdjson_warn_unused simdjson_inline simdjson_result<document>
parser::iterate(std::string &json) & noexcept {
103 return iterate(padded_string_view(json));
106 simdjson_warn_unused simdjson_inline simdjson_result<document>
parser::iterate(
const std::string &json) & noexcept {
107 return iterate(padded_string_view(json));
110 simdjson_warn_unused simdjson_inline simdjson_result<document>
parser::iterate(
const simdjson_result<padded_string_view> &result) & noexcept {
112 SIMDJSON_TRY( result.error() );
113 padded_string_view json = result.value_unsafe();
114 return iterate(json);
117 simdjson_warn_unused simdjson_inline simdjson_result<document>
parser::iterate(
const simdjson_result<padded_string> &result) & noexcept {
119 SIMDJSON_TRY( result.error() );
120 const padded_string &json = result.value_unsafe();
121 return iterate(json);
124 simdjson_warn_unused simdjson_inline simdjson_result<json_iterator> parser::iterate_raw(padded_string_view json) & noexcept {
127 json.remove_utf8_bom();
130 if (capacity() < json.length()) {
131 SIMDJSON_TRY( allocate(json.length(), max_depth()) );
135 SIMDJSON_TRY( implementation->stage1(
reinterpret_cast<const uint8_t *
>(json.data()), json.length(), stage1_mode::regular) );
136 return json_iterator(
reinterpret_cast<const uint8_t *
>(json.data()),
this);
140 if(batch_size < MINIMAL_BATCH_SIZE) { batch_size = MINIMAL_BATCH_SIZE; }
141 if((len >= 3) && (std::memcmp(buf,
"\xEF\xBB\xBF", 3) == 0)) {
145 if(allow_comma_separated && batch_size < len) { batch_size = len; }
146 return document_stream(*
this, buf, len, batch_size, allow_comma_separated);
149 return iterate_many(
reinterpret_cast<const uint8_t *
>(buf), len, batch_size, allow_comma_separated);
152 return iterate_many(s.data(), s.length(), batch_size, allow_comma_separated);
155 return iterate_many(s.data(), s.length(), batch_size, allow_comma_separated);
162 return _max_capacity;
168 simdjson_inline
void parser::set_max_capacity(
size_t max_capacity) noexcept {
169 if(max_capacity < dom::MINIMAL_DOCUMENT_CAPACITY) {
170 _max_capacity = max_capacity;
172 _max_capacity = dom::MINIMAL_DOCUMENT_CAPACITY;
177 uint8_t *end =
implementation->parse_string(in.buf, dst, allow_replacement);
179 std::string_view result(
reinterpret_cast<const char *
>(dst), end-dst);
187 std::string_view result(
reinterpret_cast<const char *
>(dst), end-dst);
198 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::parser>::simdjson_result(SIMDJSON_IMPLEMENTATION::ondemand::parser &&value) noexcept
199 : implementation_simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::parser>(std::forward<SIMDJSON_IMPLEMENTATION::ondemand::parser>(value)) {}
200 simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::parser>::simdjson_result(
error_code error) noexcept
201 : implementation_simdjson_result_base<SIMDJSON_IMPLEMENTATION::ondemand::parser>(error) {}
A forward-only stream of documents.
simdjson_warn_unused simdjson_result< document > iterate(padded_string_view json) &noexcept
Start iterating an on-demand JSON document.
simdjson_pure simdjson_inline size_t max_capacity() const noexcept
The maximum capacity of this parser (the largest document it is allowed to process).
simdjson_inline simdjson_result< std::string_view > unescape(raw_json_string in, uint8_t *&dst, bool allow_replacement=false) const noexcept
Unescape this JSON string, replacing \ with \, with newline, etc.
simdjson_pure simdjson_inline size_t max_depth() const noexcept
The maximum depth of this parser (the most deeply nested objects and arrays it can process).
simdjson_pure simdjson_inline size_t capacity() const noexcept
The capacity of this parser (the largest document it can process).
parser(size_t max_capacity=SIMDJSON_MAXSIZE_BYTES) noexcept
Create a JSON parser.
simdjson_inline simdjson_result< std::string_view > unescape_wobbly(raw_json_string in, uint8_t *&dst) const noexcept
Unescape this JSON string, replacing \ with \, with newline, etc.
simdjson_warn_unused error_code allocate(size_t capacity, size_t max_depth=DEFAULT_MAX_DEPTH) noexcept
Ensure this parser has enough memory to process JSON documents up to capacity bytes in length and max...
simdjson_result< document_stream > iterate_many(const uint8_t *buf, size_t len, size_t batch_size=DEFAULT_BATCH_SIZE, bool allow_comma_separated=false) noexcept
Parse a buffer containing many JSON documents.
A string escaped per JSON rules, terminated with quote (").
An implementation of simdjson for a particular CPU architecture.
User-provided string that promises it has extra padded bytes at the end for use with parser::parse().
The top level simdjson namespace, containing everything the library provides.
error_code
All possible errors returned by simdjson.
@ UNCLOSED_STRING
missing quote at the end
@ CAPACITY
This parser can't support a document that big.
@ STRING_ERROR
Problem while parsing a string.
@ INSUFFICIENT_PADDING
The JSON doesn't have enough padding for simdjson to safely parse it.
SIMDJSON_DLLIMPORTEXPORT internal::atomic_ptr< const implementation > & get_active_implementation()
The active implementation.
constexpr size_t SIMDJSON_PADDING
The amount of padding needed in a buffer to parse JSON.
String with extra allocation for ease of use with parser::parse()
The result of a simdjson operation that could fail.