mirror of
https://github.com/simdjson/simdjson
synced 2026-06-08 17:27:07 +00:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0d2455029d | |||
| e94f027310 | |||
| 2b766e4c09 | |||
| a5db75e1a6 | |||
| 4bd66cb891 | |||
| 960a7ebba1 | |||
| d520062f8e | |||
| db08d78ed0 | |||
| 46292b8d4b | |||
| 46241287c6 | |||
| 137cb14bcc | |||
| 5e6be3ed7a |
@@ -1,34 +0,0 @@
|
||||
name: Macos (Xcode 11)
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
macos-build:
|
||||
if: >-
|
||||
! contains(toJSON(github.event.commits.*.message), '[skip ci]') &&
|
||||
! contains(toJSON(github.event.commits.*.message), '[skip github]')
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: dependencies/.cache
|
||||
key: ${{ hashFiles('dependencies/CMakeLists.txt') }}
|
||||
- name: Use cmake
|
||||
run: |
|
||||
xcversion select 11.7
|
||||
mkdir builddebug &&
|
||||
cd builddebug &&
|
||||
cmake -DCMAKE_BUILD_TYPE=Debug -DSIMDJSON_GOOGLE_BENCHMARKS=OFF -DSIMDJSON_DEVELOPER_MODE=ON -DBUILD_SHARED_LIBS=OFF .. &&
|
||||
cmake --build . &&
|
||||
ctest -j --output-on-failure -LE explicitonly &&
|
||||
cd .. &&
|
||||
mkdir build &&
|
||||
cd build &&
|
||||
cmake -DSIMDJSON_GOOGLE_BENCHMARKS=ON -DSIMDJSON_DEVELOPER_MODE=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX:PATH=destination .. &&
|
||||
cmake --build . &&
|
||||
ctest -j --output-on-failure -LE explicitonly &&
|
||||
cmake --install . &&
|
||||
echo -e '#include <simdjson.h>\nint main(int argc,char**argv) {simdjson::dom::parser parser;simdjson::dom::element tweets = parser.load(argv[1]); }' > tmp.cpp && c++ -Idestination/include -Ldestination/lib -std=c++17 -Wl,-rpath,destination/lib -o linkandrun tmp.cpp -lsimdjson && ./linkandrun jsonexamples/twitter.json &&
|
||||
cd ../tests/installation_tests/find &&
|
||||
mkdir build && cd build && cmake -DCMAKE_INSTALL_PREFIX:PATH=../../../build/destination .. && cmake --build .
|
||||
+3
-3
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.14)
|
||||
project(
|
||||
simdjson
|
||||
# The version number is modified by tools/release.py
|
||||
VERSION 2.2.3
|
||||
VERSION 3.0.1
|
||||
DESCRIPTION "Parsing gigabytes of JSON per second"
|
||||
HOMEPAGE_URL "https://simdjson.org/"
|
||||
LANGUAGES CXX C
|
||||
@@ -20,8 +20,8 @@ string(
|
||||
# ---- Options, variables ----
|
||||
|
||||
# These version numbers are modified by tools/release.py
|
||||
set(SIMDJSON_LIB_VERSION "13.0.0" CACHE STRING "simdjson library version")
|
||||
set(SIMDJSON_LIB_SOVERSION "13" CACHE STRING "simdjson library soversion")
|
||||
set(SIMDJSON_LIB_VERSION "14.0.0" CACHE STRING "simdjson library version")
|
||||
set(SIMDJSON_LIB_SOVERSION "14" CACHE STRING "simdjson library soversion")
|
||||
|
||||
option(SIMDJSON_ENABLE_THREADS "Link with thread support" ON)
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ PROJECT_NAME = simdjson
|
||||
# could be handy for archiving the generated documentation or if some version
|
||||
# control system is used.
|
||||
|
||||
PROJECT_NUMBER = "2.2.3"
|
||||
PROJECT_NUMBER = "3.0.1"
|
||||
|
||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||
# for a project that appears at the top of each page and should give viewer a
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
[/badge.svg)](https://simdjson.org/plots.html)
|
||||

|
||||

|
||||
[![][license img]][license] [](https://simdjson.org/api/2.0.0/index.html)
|
||||
[![][license img]][license] [](https://simdjson.org/api/3.0.0/index.html)
|
||||
|
||||
simdjson : Parsing gigabytes of JSON per second
|
||||
===============================================
|
||||
|
||||
@@ -51,6 +51,7 @@ private:
|
||||
simdjson_inline void
|
||||
write_raw_string(simdjson::ondemand::raw_json_string rjs);
|
||||
inline void recursive_processor(simdjson::ondemand::value element);
|
||||
inline void recursive_processor_ref(simdjson::ondemand::value& element);
|
||||
|
||||
simdjson::ondemand::parser parser;
|
||||
uint8_t *buff{};
|
||||
@@ -74,17 +75,34 @@ simdjson2msgpack::to_msgpack(const simdjson::padded_string &json,
|
||||
write_byte(0xc2 + doc.get_bool());
|
||||
break;
|
||||
case simdjson::ondemand::json_type::null:
|
||||
write_byte(0xc0);
|
||||
// We check that the value is indeed null
|
||||
// otherwise: an error is thrown.
|
||||
if(doc.is_null()) {
|
||||
write_byte(0xc0);
|
||||
}
|
||||
break;
|
||||
case simdjson::ondemand::json_type::array:
|
||||
case simdjson::ondemand::json_type::object:
|
||||
default:
|
||||
// impossible
|
||||
break;
|
||||
SIMDJSON_UNREACHABLE();
|
||||
}
|
||||
} else {
|
||||
simdjson::ondemand::value val = doc;
|
||||
#define SIMDJSON_GCC_COMPILER ((__GNUC__) && !(__clang__) && !(__INTEL_COMPILER))
|
||||
#if SIMDJSON_GCC_COMPILER
|
||||
// the GCC compiler does well with by-value passing.
|
||||
// GCC has superior recursive inlining:
|
||||
// https://stackoverflow.com/questions/29186186/why-does-gcc-generate-a-faster-program-than-clang-in-this-recursive-fibonacci-co
|
||||
// https://godbolt.org/z/TeK4doE51
|
||||
recursive_processor(val);
|
||||
#else
|
||||
recursive_processor_ref(val);
|
||||
#endif
|
||||
}
|
||||
if (doc.current_location().error() == simdjson::SUCCESS) {
|
||||
// Example of error detection - this won't be reached on twitter.json in the benchmark.
|
||||
throw "There are unexpectedly tokens after the end of the json in the json2msgpack sample data";
|
||||
}
|
||||
return std::string_view(reinterpret_cast<char *>(buf), size_t(buff - buf));
|
||||
}
|
||||
@@ -156,7 +174,58 @@ void simdjson2msgpack::recursive_processor(simdjson::ondemand::value element) {
|
||||
write_byte(0xc2 + element.get_bool());
|
||||
break;
|
||||
case simdjson::ondemand::json_type::null:
|
||||
write_byte(0xc0);
|
||||
// We check that the value is indeed null
|
||||
// otherwise: an error is thrown.
|
||||
if(element.is_null()) {
|
||||
write_byte(0xc0);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
SIMDJSON_UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void simdjson2msgpack::recursive_processor_ref(simdjson::ondemand::value& element) {
|
||||
switch (element.type()) {
|
||||
case simdjson::ondemand::json_type::array: {
|
||||
uint32_t counter = 0;
|
||||
write_byte(0xdd);
|
||||
uint8_t *location = skip_uint32();
|
||||
for (auto child : element.get_array()) {
|
||||
counter++;
|
||||
simdjson::ondemand::value v = child.value();
|
||||
recursive_processor_ref(v);
|
||||
}
|
||||
write_uint32_at(counter, location);
|
||||
} break;
|
||||
case simdjson::ondemand::json_type::object: {
|
||||
uint32_t counter = 0;
|
||||
write_byte(0xdf);
|
||||
uint8_t *location = skip_uint32();
|
||||
for (auto field : element.get_object()) {
|
||||
counter++;
|
||||
write_raw_string(field.key());
|
||||
simdjson::ondemand::value v = field.value();
|
||||
recursive_processor_ref(v);
|
||||
}
|
||||
write_uint32_at(counter, location);
|
||||
} break;
|
||||
case simdjson::ondemand::json_type::number:
|
||||
write_double(element.get_double());
|
||||
break;
|
||||
case simdjson::ondemand::json_type::string:
|
||||
write_raw_string(element.get_raw_json_string());
|
||||
break;
|
||||
case simdjson::ondemand::json_type::boolean:
|
||||
write_byte(0xc2 + element.get_bool());
|
||||
break;
|
||||
case simdjson::ondemand::json_type::null:
|
||||
// We check that the value is indeed null
|
||||
// otherwise: an error is thrown.
|
||||
if(element.is_null()) {
|
||||
write_byte(0xc0);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
SIMDJSON_UNREACHABLE();
|
||||
|
||||
+27
-8
@@ -482,8 +482,20 @@ support for users who avoid exceptions. See [the simdjson error handling documen
|
||||
std::cout << "Number of fields: " << count << std::endl; // Prints "Number of fields: 2"
|
||||
```
|
||||
* **Tree Walking and JSON Element Types:** Sometimes you don't necessarily have a document
|
||||
with a known type, and are trying to generically inspect or walk over JSON elements. To do that, you can use iterators and the `type()` method. You can also represent arbitrary JSON values with
|
||||
`ondemand::value` instances: it can represent anything except a scalar document (lone number, string, null or Boolean). You can check for scalar documents with the method `scalar()`. You may also access [raw strings](#raw-strings).
|
||||
with a known type, and are trying to generically inspect or walk over JSON elements.
|
||||
You can also represent arbitrary JSON values with
|
||||
`ondemand::value` instances: it can represent anything except a scalar document (lone number, string, null or Boolean). You can check for scalar documents with the method `scalar()`.
|
||||
You can query the type of a document or a value with the `type()` method.
|
||||
The `type()` method does not consume or validate documents and values, but it tells you whether they are
|
||||
- arrays (`json_type::array`),
|
||||
- objects (`json_type::object`)
|
||||
- numbers (`json_type::number`),
|
||||
- strings (`json_type::string`),
|
||||
- Booleans (`json_type::boolean`),
|
||||
- null (`json_type::null`).
|
||||
|
||||
You must still validate and consume the values (e.g., call `is_null()`) after calling `type()`.
|
||||
You may also access [raw strings](#raw-strings).
|
||||
For example, the following is a quick and dirty recursive function that verbosely prints the JSON document as JSON. This example also illustrates lifecycle requirements: the `document` instance holds the iterator. The document must remain in scope while you are accessing instances of `value`, `object` and `array`.
|
||||
```c++
|
||||
void recursive_print_json(ondemand::value element) {
|
||||
@@ -532,7 +544,11 @@ support for users who avoid exceptions. See [the simdjson error handling documen
|
||||
cout << element.get_bool();
|
||||
break;
|
||||
case ondemand::json_type::null:
|
||||
cout << "null";
|
||||
// We check that the value is indeed null
|
||||
// otherwise: an error is thrown.
|
||||
if(element.is_null()) {
|
||||
cout << "null";
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -931,11 +947,11 @@ bool parse() {
|
||||
// Iterating through an array of objects
|
||||
auto error = parser.iterate(cars_json).get(doc);
|
||||
if(error) { std::cerr << error << std::endl; return false; }
|
||||
ondemand::array cars;
|
||||
ondemand::array cars; // invalid until the get() succeeds
|
||||
error = doc.get_array().get(cars);
|
||||
|
||||
for (auto car_value : cars) {
|
||||
ondemand::object car;
|
||||
ondemand::object car; // invalid until the get() succeeds
|
||||
error = car_value.get_object().get(car);
|
||||
if(error) { std::cerr << error << std::endl; return false; }
|
||||
|
||||
@@ -976,7 +992,7 @@ For safety, you should only use our ondemand instances (e.g., `ondemand::object`
|
||||
after you have initialized them and checked that there is no error:
|
||||
|
||||
```c++
|
||||
ondemand::object car;
|
||||
ondemand::object car; // invalid until the get() succeeds
|
||||
// the `car` instance should not use used before it is initialized
|
||||
error = car_value.get_object().get(car);
|
||||
if(error) {
|
||||
@@ -994,7 +1010,7 @@ having to handle exceptions.
|
||||
ondemand::document doc;
|
||||
auto error = parser.iterate(json).get(doc);
|
||||
if(error) { return false; }
|
||||
ondemand::object object;
|
||||
ondemand::object object; // invalid until the get() succeeds
|
||||
error = doc.get_object().get(object);
|
||||
if(error) { return false; }
|
||||
for(auto field : object) {
|
||||
@@ -1110,6 +1126,9 @@ for (auto val : doc) {
|
||||
std::cout << doc.current_location() << std::endl; // Throws OUT_OF_BOUNDS
|
||||
```
|
||||
|
||||
Conversely, if `doc.current_location().error() == simdjson::SUCCESS`,
|
||||
then the document has more content.
|
||||
|
||||
Finally, the `current_location()` method may also be used even when no exceptions/errors
|
||||
are thrown. This can be helpful for users that want to know the current state of iteration during parsing. For example:
|
||||
|
||||
@@ -1118,7 +1137,7 @@ auto json = R"( [[1,2,3], -23.4, {"key": "value"}, true] )"_padded;
|
||||
ondemand::parser parser;
|
||||
auto doc = parser.iterate(json);
|
||||
for (auto val : doc) {
|
||||
ondemand::object obj;
|
||||
ondemand::object obj; // invalid until the get() succeeds
|
||||
auto error = val.get_object().get(obj); // Only get objects
|
||||
if (!error) {
|
||||
std::cout << doc.current_location() << std::endl; // Prints ""key": "value"}, true] "
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
We take our documentation seriously. Please start reading the documentation before you attempt to use simdjson. We hope you will enjoy reading us.
|
||||
|
||||
* Basics: https://github.com/simdjson/simdjson/blob/master/doc/basics.md is an overview of how to use simdjson and its APIs.
|
||||
* parse_many: https://github.com/simdjson/simdjson/blob/master/doc/parse_many.md describes an interface providing features to work with files or streams containing multiple small JSON documents. As fast and convenient as possible.
|
||||
* iterate_many: https://github.com/simdjson/simdjson/blob/master/doc/iterate_many.md describes an interface providing features to work with files or streams containing multiple small JSON documents. As fast and convenient as possible.
|
||||
* Performance: https://github.com/simdjson/simdjson/blob/master/doc/performance.md shows some more advanced scenarios and how to tune for them.
|
||||
|
||||
+9
-9
@@ -47,7 +47,7 @@ dom::element doc = parser.parse("[1,2,3]"_padded); // parse a string, the _padde
|
||||
The parsed document resulting from the `parser.load` and `parser.parse` calls depends on the `parser` instance. Thus the `parser` instance must remain in scope. Furthermore, you must have at most one parsed document in play per `parser` instance.
|
||||
You cannot copy a `parser` instance, you may only move it.
|
||||
|
||||
If you need to keep a document around long term, you can keep or move the parser instance. Note that moving a parser instance, or keeping one in a movable data structure like vector or map, can cause any outstanding `element`, `object` or `array` instances to be invalidated. If you need to store a parser in a movable data structure, you should use a `std::unique_ptr` to avoid this invalidation(e.g., `std::unique_ptr<dom::parser> parser(new dom::parser{})`).
|
||||
If you need to keep a document around long term, you can keep or move the parser instance. Note that moving a parser instance, or keeping one in a movable data structure like vector or map, can cause any outstanding `element`, `object` or `array` instances to be invalidated. The `element`, `object` or `array` instances are mere thin wrappers akin to an `std::vector<int>::iterator`: they are invalid when default constructed, they must be tied to a valid document instance. If you need to store a parser in a movable data structure, you should use a `std::unique_ptr` to avoid this invalidation(e.g., `std::unique_ptr<dom::parser> parser(new dom::parser{})`).
|
||||
|
||||
During the`load` or `parse` calls, neither the input file nor the input string are ever modified. After calling `load` or `parse`, the source (either a file or a string) can be safely discarded. All of the JSON data is stored in the `parser` instance. The parsed document is also immutable in simdjson: you do not modify it by accessing it.
|
||||
|
||||
@@ -167,7 +167,7 @@ While the simdjson library can be used in any project using C++ 11 and above, fi
|
||||
```c++
|
||||
padded_string json = R"( { "foo": 1, "bar": 2 } )"_padded;
|
||||
dom::parser parser;
|
||||
dom::object object;
|
||||
dom::object object; // invalid until the get() succeeds
|
||||
auto error = parser.parse(json).get(object);
|
||||
if (error) { cerr << error << endl; return; }
|
||||
for (auto [key, value] : object) {
|
||||
@@ -181,7 +181,7 @@ For comparison, here is the C++ 11 version of the same code:
|
||||
// C++ 11 version for comparison
|
||||
padded_string json = R"( { "foo": 1, "bar": 2 } )"_padded;
|
||||
dom::parser parser;
|
||||
dom::object object;
|
||||
dom::object object; // invalid until the get() succeeds
|
||||
auto error = parser.parse(json).get(object);
|
||||
if (error) { cerr << error << endl; return; }
|
||||
for (dom::key_value_pair field : object) {
|
||||
@@ -227,7 +227,7 @@ dom::parser parser;
|
||||
dom::element cars = parser.parse(cars_json);
|
||||
cout << cars.at_pointer("/0/tire_pressure/1") << endl; // Prints 39.9
|
||||
for (dom::element car_element : cars) {
|
||||
dom::object car;
|
||||
dom::object car; // invalid until the get() succeeds
|
||||
simdjson::error_code error;
|
||||
if ((error = car_element.get(car))) { std::cerr << error << std::endl; return; }
|
||||
double x = car.at_pointer("/tire_pressure/1");
|
||||
@@ -283,11 +283,11 @@ it selects the key "count" within that object.
|
||||
|
||||
int main(void) {
|
||||
simdjson::dom::parser parser;
|
||||
simdjson::dom::element tweets;
|
||||
simdjson::dom::element tweets; // invalid until the get() succeeds
|
||||
auto error = parser.load("twitter.json").get(tweets);
|
||||
if (error) { std::cerr << error << std::endl; return EXIT_FAILURE; }
|
||||
|
||||
simdjson::dom::element res;
|
||||
simdjson::dom::element res; // invalid until the get() succeeds
|
||||
if ((error = tweets["search_metadata"]["count"].get(res))) {
|
||||
std::cerr << "could not access keys" << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
@@ -311,7 +311,7 @@ Observe how we use the `at` method when querying an index into an array, and not
|
||||
|
||||
int main(void) {
|
||||
simdjson::dom::parser parser;
|
||||
simdjson::dom::element tweets;
|
||||
simdjson::dom::element tweets; // invalid until the get() succeeds
|
||||
auto error = parser.load("twitter.json").get(tweets);
|
||||
if(error) { std::cerr << error << std::endl; return EXIT_FAILURE; }
|
||||
uint64_t identifier;
|
||||
@@ -336,7 +336,7 @@ auto cars_json = R"( [
|
||||
{ "make": "Toyota", "model": "Tercel", "year": 1999, "tire_pressure": [ 29.8, 30.0, 30.2, 30.5 ] }
|
||||
] )"_padded;
|
||||
dom::parser parser;
|
||||
dom::array cars;
|
||||
dom::array cars; // invalid until the get() succeeds
|
||||
auto error = parser.parse(cars_json).get(cars);
|
||||
if (error) { cerr << error << endl; exit(1); }
|
||||
|
||||
@@ -382,7 +382,7 @@ auto abstract_json = R"( [
|
||||
{ "12545" : {"a":11.44, "b":12.78, "c": 11111111} }
|
||||
] )"_padded;
|
||||
dom::parser parser;
|
||||
dom::array array;
|
||||
dom::array array; // invalid until after the next line
|
||||
auto error = parser.parse(abstract_json).get(array);
|
||||
if (error) { cerr << error << endl; exit(1); }
|
||||
// Iterate through an array of objects
|
||||
|
||||
@@ -322,4 +322,11 @@ namespace std {
|
||||
# define simdjson_fallthrough do {} while (0) /* fallthrough */
|
||||
#endif // simdjson_fallthrough
|
||||
|
||||
|
||||
#if SIMDJSON_DEVELOPMENT_CHECKS
|
||||
#define SIMDJSON_DEVELOPMENT_ASSERT(expr) do { assert ((expr)); } while (0)
|
||||
#else
|
||||
#define SIMDJSON_DEVELOPMENT_ASSERT(expr) do { } while (0)
|
||||
#endif
|
||||
|
||||
#endif // SIMDJSON_COMMON_DEFS_H
|
||||
|
||||
@@ -53,18 +53,23 @@ namespace dom {
|
||||
simdjson_inline array::array() noexcept : tape{} {}
|
||||
simdjson_inline array::array(const internal::tape_ref &_tape) noexcept : tape{_tape} {}
|
||||
inline array::iterator array::begin() const noexcept {
|
||||
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
|
||||
return internal::tape_ref(tape.doc, tape.json_index + 1);
|
||||
}
|
||||
inline array::iterator array::end() const noexcept {
|
||||
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
|
||||
return internal::tape_ref(tape.doc, tape.after_element() - 1);
|
||||
}
|
||||
inline size_t array::size() const noexcept {
|
||||
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
|
||||
return tape.scope_count();
|
||||
}
|
||||
inline size_t array::number_of_slots() const noexcept {
|
||||
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
|
||||
return tape.matching_brace_index() - tape.json_index;
|
||||
}
|
||||
inline simdjson_result<element> array::at_pointer(std::string_view json_pointer) const noexcept {
|
||||
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
|
||||
if(json_pointer.empty()) { // an empty string means that we return the current node
|
||||
return element(this->tape); // copy the current node
|
||||
} else if(json_pointer[0] != '/') { // otherwise there is an error
|
||||
@@ -105,6 +110,7 @@ inline simdjson_result<element> array::at_pointer(std::string_view json_pointer)
|
||||
}
|
||||
|
||||
inline simdjson_result<element> array::at(size_t index) const noexcept {
|
||||
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
|
||||
size_t i=0;
|
||||
for (auto element : *this) {
|
||||
if (i == index) { return element; }
|
||||
|
||||
@@ -186,11 +186,13 @@ simdjson_inline element::element() noexcept : tape{} {}
|
||||
simdjson_inline element::element(const internal::tape_ref &_tape) noexcept : tape{_tape} { }
|
||||
|
||||
inline element_type element::type() const noexcept {
|
||||
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
|
||||
auto tape_type = tape.tape_ref_type();
|
||||
return tape_type == internal::tape_type::FALSE_VALUE ? element_type::BOOL : static_cast<element_type>(tape_type);
|
||||
}
|
||||
|
||||
inline simdjson_result<bool> element::get_bool() const noexcept {
|
||||
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
|
||||
if(tape.is_true()) {
|
||||
return true;
|
||||
} else if(tape.is_false()) {
|
||||
@@ -199,6 +201,7 @@ inline simdjson_result<bool> element::get_bool() const noexcept {
|
||||
return INCORRECT_TYPE;
|
||||
}
|
||||
inline simdjson_result<const char *> element::get_c_str() const noexcept {
|
||||
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
|
||||
switch (tape.tape_ref_type()) {
|
||||
case internal::tape_type::STRING: {
|
||||
return tape.get_c_str();
|
||||
@@ -208,6 +211,7 @@ inline simdjson_result<const char *> element::get_c_str() const noexcept {
|
||||
}
|
||||
}
|
||||
inline simdjson_result<size_t> element::get_string_length() const noexcept {
|
||||
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
|
||||
switch (tape.tape_ref_type()) {
|
||||
case internal::tape_type::STRING: {
|
||||
return tape.get_string_length();
|
||||
@@ -217,6 +221,7 @@ inline simdjson_result<size_t> element::get_string_length() const noexcept {
|
||||
}
|
||||
}
|
||||
inline simdjson_result<std::string_view> element::get_string() const noexcept {
|
||||
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
|
||||
switch (tape.tape_ref_type()) {
|
||||
case internal::tape_type::STRING:
|
||||
return tape.get_string_view();
|
||||
@@ -225,6 +230,7 @@ inline simdjson_result<std::string_view> element::get_string() const noexcept {
|
||||
}
|
||||
}
|
||||
inline simdjson_result<uint64_t> element::get_uint64() const noexcept {
|
||||
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
|
||||
if(simdjson_unlikely(!tape.is_uint64())) { // branch rarely taken
|
||||
if(tape.is_int64()) {
|
||||
int64_t result = tape.next_tape_value<int64_t>();
|
||||
@@ -238,6 +244,7 @@ inline simdjson_result<uint64_t> element::get_uint64() const noexcept {
|
||||
return tape.next_tape_value<int64_t>();
|
||||
}
|
||||
inline simdjson_result<int64_t> element::get_int64() const noexcept {
|
||||
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
|
||||
if(simdjson_unlikely(!tape.is_int64())) { // branch rarely taken
|
||||
if(tape.is_uint64()) {
|
||||
uint64_t result = tape.next_tape_value<uint64_t>();
|
||||
@@ -252,6 +259,7 @@ inline simdjson_result<int64_t> element::get_int64() const noexcept {
|
||||
return tape.next_tape_value<int64_t>();
|
||||
}
|
||||
inline simdjson_result<double> element::get_double() const noexcept {
|
||||
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
|
||||
// Performance considerations:
|
||||
// 1. Querying tape_ref_type() implies doing a shift, it is fast to just do a straight
|
||||
// comparison.
|
||||
@@ -273,6 +281,7 @@ inline simdjson_result<double> element::get_double() const noexcept {
|
||||
return tape.next_tape_value<double>();
|
||||
}
|
||||
inline simdjson_result<array> element::get_array() const noexcept {
|
||||
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
|
||||
switch (tape.tape_ref_type()) {
|
||||
case internal::tape_type::START_ARRAY:
|
||||
return array(tape);
|
||||
@@ -281,6 +290,7 @@ inline simdjson_result<array> element::get_array() const noexcept {
|
||||
}
|
||||
}
|
||||
inline simdjson_result<object> element::get_object() const noexcept {
|
||||
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
|
||||
switch (tape.tape_ref_type()) {
|
||||
case internal::tape_type::START_OBJECT:
|
||||
return object(tape);
|
||||
@@ -360,6 +370,7 @@ inline simdjson_result<element> element::operator[](const char *key) const noexc
|
||||
}
|
||||
|
||||
inline simdjson_result<element> element::at_pointer(std::string_view json_pointer) const noexcept {
|
||||
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
|
||||
switch (tape.tape_ref_type()) {
|
||||
case internal::tape_type::START_OBJECT:
|
||||
return object(tape).at_pointer(json_pointer);
|
||||
@@ -395,6 +406,7 @@ inline simdjson_result<element> element::at_key_case_insensitive(std::string_vie
|
||||
}
|
||||
|
||||
inline bool element::dump_raw_tape(std::ostream &out) const noexcept {
|
||||
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
|
||||
return tape.doc->dump_raw_tape(out);
|
||||
}
|
||||
|
||||
|
||||
@@ -65,12 +65,15 @@ namespace dom {
|
||||
simdjson_inline object::object() noexcept : tape{} {}
|
||||
simdjson_inline object::object(const internal::tape_ref &_tape) noexcept : tape{_tape} { }
|
||||
inline object::iterator object::begin() const noexcept {
|
||||
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
|
||||
return internal::tape_ref(tape.doc, tape.json_index + 1);
|
||||
}
|
||||
inline object::iterator object::end() const noexcept {
|
||||
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
|
||||
return internal::tape_ref(tape.doc, tape.after_element() - 1);
|
||||
}
|
||||
inline size_t object::size() const noexcept {
|
||||
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
|
||||
return tape.scope_count();
|
||||
}
|
||||
|
||||
@@ -81,6 +84,7 @@ inline simdjson_result<element> object::operator[](const char *key) const noexce
|
||||
return at_key(key);
|
||||
}
|
||||
inline simdjson_result<element> object::at_pointer(std::string_view json_pointer) const noexcept {
|
||||
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
|
||||
if(json_pointer.empty()) { // an empty string means that we return the current node
|
||||
return element(this->tape); // copy the current node
|
||||
} else if(json_pointer[0] != '/') { // otherwise there is an error
|
||||
|
||||
@@ -148,6 +148,9 @@ simdjson_inline simdjson_result<element> parser::parse(const std::string &s) & n
|
||||
simdjson_inline simdjson_result<element> parser::parse(const padded_string &s) & noexcept {
|
||||
return parse(s.data(), s.length(), false);
|
||||
}
|
||||
simdjson_inline simdjson_result<element> parser::parse(const padded_string_view &v) & noexcept {
|
||||
return parse(v.data(), v.length(), false);
|
||||
}
|
||||
|
||||
inline simdjson_result<document_stream> parser::parse_many(const uint8_t *buf, size_t len, size_t batch_size) noexcept {
|
||||
if(batch_size < MINIMAL_BATCH_SIZE) { batch_size = MINIMAL_BATCH_SIZE; }
|
||||
|
||||
@@ -199,6 +199,9 @@ public:
|
||||
/** @overload parse(const uint8_t *buf, size_t len, bool realloc_if_needed) */
|
||||
simdjson_inline simdjson_result<element> parse(const padded_string &s) & noexcept;
|
||||
simdjson_inline simdjson_result<element> parse(const padded_string &s) && =delete;
|
||||
/** @overload parse(const uint8_t *buf, size_t len, bool realloc_if_needed) */
|
||||
simdjson_inline simdjson_result<element> parse(const padded_string_view &v) & noexcept;
|
||||
simdjson_inline simdjson_result<element> parse(const padded_string_view &v) && =delete;
|
||||
|
||||
/** @private We do not want to allow implicit conversion from C string to std::string. */
|
||||
simdjson_inline simdjson_result<element> parse(const char *buf) noexcept = delete;
|
||||
|
||||
@@ -94,7 +94,7 @@ simdjson_inline simdjson_result<raw_json_string> document::get_raw_json_string()
|
||||
simdjson_inline simdjson_result<bool> document::get_bool() noexcept {
|
||||
return get_root_value_iterator().get_root_bool();
|
||||
}
|
||||
simdjson_inline bool document::is_null() noexcept {
|
||||
simdjson_inline simdjson_result<bool> document::is_null() noexcept {
|
||||
return get_root_value_iterator().is_root_null();
|
||||
}
|
||||
|
||||
@@ -354,7 +354,7 @@ simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> simdjs
|
||||
if (error()) { return error(); }
|
||||
return first.get_value();
|
||||
}
|
||||
simdjson_inline bool simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::is_null() noexcept {
|
||||
simdjson_inline simdjson_result<bool> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::is_null() noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.is_null();
|
||||
}
|
||||
@@ -504,7 +504,7 @@ simdjson_inline simdjson_result<std::string_view> document_reference::get_string
|
||||
simdjson_inline simdjson_result<raw_json_string> document_reference::get_raw_json_string() noexcept { return doc->get_raw_json_string(); }
|
||||
simdjson_inline simdjson_result<bool> document_reference::get_bool() noexcept { return doc->get_bool(); }
|
||||
simdjson_inline simdjson_result<value> document_reference::get_value() noexcept { return doc->get_value(); }
|
||||
simdjson_inline bool document_reference::is_null() noexcept { return doc->is_null(); }
|
||||
simdjson_inline simdjson_result<bool> document_reference::is_null() noexcept { return doc->is_null(); }
|
||||
|
||||
#if SIMDJSON_EXCEPTIONS
|
||||
simdjson_inline document_reference::operator array() & noexcept(false) { return array(*doc); }
|
||||
@@ -636,7 +636,7 @@ simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> simdjs
|
||||
if (error()) { return error(); }
|
||||
return first.get_value();
|
||||
}
|
||||
simdjson_inline bool simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::is_null() noexcept {
|
||||
simdjson_inline simdjson_result<bool> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::is_null() noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.is_null();
|
||||
}
|
||||
@@ -648,7 +648,7 @@ simdjson_inline simdjson_result<bool> simdjson_result<SIMDJSON_IMPLEMENTATION::o
|
||||
if (error()) { return error(); }
|
||||
return first.is_scalar();
|
||||
}
|
||||
simdjson_inline bool simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::is_negative() noexcept {
|
||||
simdjson_inline simdjson_result<bool> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::is_negative() noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.is_negative();
|
||||
}
|
||||
|
||||
@@ -126,11 +126,14 @@ public:
|
||||
simdjson_inline simdjson_result<value> get_value() noexcept;
|
||||
|
||||
/**
|
||||
* Checks if this JSON value is null.
|
||||
* Checks if this JSON value is null. If and only if the value is
|
||||
* null, then it is consumed (we advance). If we find a token that
|
||||
* begins with 'n' but is not 'null', then an error is returned.
|
||||
*
|
||||
* @returns Whether the value is null.
|
||||
* @returns INCORRECT_TYPE If the JSON value begins with 'n' and is not 'null'.
|
||||
*/
|
||||
simdjson_inline bool is_null() noexcept;
|
||||
simdjson_inline simdjson_result<bool> is_null() noexcept;
|
||||
|
||||
/**
|
||||
* Get this value as the given type.
|
||||
@@ -363,7 +366,9 @@ public:
|
||||
simdjson_inline simdjson_result<value> operator[](const char *key) & noexcept;
|
||||
|
||||
/**
|
||||
* Get the type of this JSON value.
|
||||
* Get the type of this JSON value. It does not validate or consume the value.
|
||||
* E.g., you must still call "is_null()" to check that a value is null even if
|
||||
* "type()" returns json_type::null.
|
||||
*
|
||||
* NOTE: If you're only expecting a value to be one type (a typical case), it's generally
|
||||
* better to just call .get_double, .get_string, etc. and check for INCORRECT_TYPE (or just
|
||||
@@ -595,7 +600,7 @@ public:
|
||||
simdjson_inline simdjson_result<bool> get_bool() noexcept;
|
||||
simdjson_inline simdjson_result<value> get_value() noexcept;
|
||||
|
||||
simdjson_inline bool is_null() noexcept;
|
||||
simdjson_inline simdjson_result<bool> is_null() noexcept;
|
||||
simdjson_inline simdjson_result<std::string_view> raw_json() noexcept;
|
||||
simdjson_inline operator document&() const noexcept;
|
||||
|
||||
@@ -660,7 +665,7 @@ public:
|
||||
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string> get_raw_json_string() noexcept;
|
||||
simdjson_inline simdjson_result<bool> get_bool() noexcept;
|
||||
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> get_value() noexcept;
|
||||
simdjson_inline bool is_null() noexcept;
|
||||
simdjson_inline simdjson_result<bool> is_null() noexcept;
|
||||
|
||||
template<typename T> simdjson_inline simdjson_result<T> get() & noexcept;
|
||||
template<typename T> simdjson_inline simdjson_result<T> get() && noexcept;
|
||||
@@ -727,7 +732,7 @@ public:
|
||||
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string> get_raw_json_string() noexcept;
|
||||
simdjson_inline simdjson_result<bool> get_bool() noexcept;
|
||||
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> get_value() noexcept;
|
||||
simdjson_inline bool is_null() noexcept;
|
||||
simdjson_inline simdjson_result<bool> is_null() noexcept;
|
||||
|
||||
#if SIMDJSON_EXCEPTIONS
|
||||
simdjson_inline operator SIMDJSON_IMPLEMENTATION::ondemand::array() & noexcept(false);
|
||||
@@ -754,8 +759,8 @@ public:
|
||||
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::json_type> type() noexcept;
|
||||
simdjson_inline simdjson_result<bool> is_scalar() noexcept;
|
||||
simdjson_inline simdjson_result<const char *> current_location() noexcept;
|
||||
simdjson_inline int32_t current_depth() const noexcept;
|
||||
simdjson_inline bool is_negative() noexcept;
|
||||
simdjson_inline simdjson_result<int32_t> current_depth() const noexcept;
|
||||
simdjson_inline simdjson_result<bool> is_negative() noexcept;
|
||||
simdjson_inline simdjson_result<bool> is_integer() noexcept;
|
||||
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::number_type> get_number_type() noexcept;
|
||||
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::number> get_number() noexcept;
|
||||
|
||||
@@ -325,6 +325,7 @@ simdjson_inline void json_iterator::reenter_child(token_position position, depth
|
||||
SIMDJSON_ASSUME(_depth == child_depth - 1);
|
||||
#if SIMDJSON_DEVELOPMENT_CHECKS
|
||||
#ifndef SIMDJSON_CLANG_VISUAL_STUDIO
|
||||
SIMDJSON_ASSUME(size_t(child_depth) < parser->max_depth());
|
||||
SIMDJSON_ASSUME(position >= parser->start_positions[child_depth]);
|
||||
#endif
|
||||
#endif
|
||||
@@ -335,11 +336,13 @@ simdjson_inline void json_iterator::reenter_child(token_position position, depth
|
||||
#if SIMDJSON_DEVELOPMENT_CHECKS
|
||||
|
||||
simdjson_inline token_position json_iterator::start_position(depth_t depth) const noexcept {
|
||||
return parser->start_positions[depth];
|
||||
SIMDJSON_ASSUME(size_t(depth) < parser->max_depth());
|
||||
return size_t(depth) < parser->max_depth() ? parser->start_positions[depth] : 0;
|
||||
}
|
||||
|
||||
simdjson_inline void json_iterator::set_start_position(depth_t depth, token_position position) noexcept {
|
||||
parser->start_positions[depth] = position;
|
||||
SIMDJSON_ASSUME(size_t(depth) < parser->max_depth());
|
||||
if(size_t(depth) < parser->max_depth()) { parser->start_positions[depth] = position; }
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -230,13 +230,22 @@ public:
|
||||
/** The maximum capacity of this parser (the largest document it is allowed to process). */
|
||||
simdjson_inline size_t max_capacity() const noexcept;
|
||||
simdjson_inline void set_max_capacity(size_t max_capacity) noexcept;
|
||||
/** The maximum depth of this parser (the most deeply nested objects and arrays it can process). */
|
||||
/**
|
||||
* The maximum depth of this parser (the most deeply nested objects and arrays it can process).
|
||||
* This parameter is only relevant when the macro SIMDJSON_DEVELOPMENT_CHECKS is set to true.
|
||||
* The document's instance current_depth() method should be used to monitor the parsing
|
||||
* depth and limit it if desired.
|
||||
*/
|
||||
simdjson_inline size_t max_depth() const noexcept;
|
||||
|
||||
/**
|
||||
* Ensure this parser has enough memory to process JSON documents up to `capacity` bytes in length
|
||||
* and `max_depth` depth.
|
||||
*
|
||||
* The max_depth parameter is only relevant when the macro SIMDJSON_DEVELOPMENT_CHECKS is set to true.
|
||||
* The document's instance current_depth() method should be used to monitor the parsing
|
||||
* depth and limit it if desired.
|
||||
*
|
||||
* @param capacity The new capacity.
|
||||
* @param max_depth The new max_depth. Defaults to DEFAULT_MAX_DEPTH.
|
||||
* @return The error, if there is one.
|
||||
|
||||
@@ -4,23 +4,27 @@
|
||||
namespace simdjson {
|
||||
/**
|
||||
* Create a string-view instance out of a document instance. The string-view instance
|
||||
* contains JSON text that is suitable to be parsed as JSON again.
|
||||
* contains JSON text that is suitable to be parsed as JSON again. It does not
|
||||
* validate the content.
|
||||
*/
|
||||
inline simdjson_result<std::string_view> to_json_string(SIMDJSON_IMPLEMENTATION::ondemand::document& x) noexcept;
|
||||
/**
|
||||
* Create a string-view instance out of a value instance. The string-view instance
|
||||
* contains JSON text that is suitable to be parsed as JSON again. The value must
|
||||
* not have been accessed previously.
|
||||
* not have been accessed previously. It does not
|
||||
* validate the content.
|
||||
*/
|
||||
inline simdjson_result<std::string_view> to_json_string(SIMDJSON_IMPLEMENTATION::ondemand::value& x) noexcept;
|
||||
/**
|
||||
* Create a string-view instance out of an object instance. The string-view instance
|
||||
* contains JSON text that is suitable to be parsed as JSON again.
|
||||
* contains JSON text that is suitable to be parsed as JSON again. It does not
|
||||
* validate the content.
|
||||
*/
|
||||
inline simdjson_result<std::string_view> to_json_string(SIMDJSON_IMPLEMENTATION::ondemand::object& x) noexcept;
|
||||
/**
|
||||
* Create a string-view instance out of an array instance. The string-view instance
|
||||
* contains JSON text that is suitable to be parsed as JSON again.
|
||||
* contains JSON text that is suitable to be parsed as JSON again. It does not
|
||||
* validate the content.
|
||||
*/
|
||||
inline simdjson_result<std::string_view> to_json_string(SIMDJSON_IMPLEMENTATION::ondemand::array& x) noexcept;
|
||||
inline simdjson_result<std::string_view> to_json_string(simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document> x);
|
||||
@@ -39,7 +43,8 @@ inline simdjson_result<std::string_view> to_json_string(simdjson_result<SIMDJSON
|
||||
namespace simdjson { namespace SIMDJSON_IMPLEMENTATION { namespace ondemand {
|
||||
|
||||
/**
|
||||
* Print JSON to an output stream.
|
||||
* Print JSON to an output stream. It does not
|
||||
* validate the content.
|
||||
*
|
||||
* @param out The output stream.
|
||||
* @param value The element.
|
||||
@@ -50,7 +55,8 @@ inline std::ostream& operator<<(std::ostream& out, simdjson::SIMDJSON_IMPLEMENTA
|
||||
inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result<simdjson::SIMDJSON_IMPLEMENTATION::ondemand::value> x);
|
||||
#endif
|
||||
/**
|
||||
* Print JSON to an output stream.
|
||||
* Print JSON to an output stream. It does not
|
||||
* validate the content.
|
||||
*
|
||||
* @param out The output stream.
|
||||
* @param value The array.
|
||||
@@ -61,7 +67,8 @@ inline std::ostream& operator<<(std::ostream& out, simdjson::SIMDJSON_IMPLEMENTA
|
||||
inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result<simdjson::SIMDJSON_IMPLEMENTATION::ondemand::array> x);
|
||||
#endif
|
||||
/**
|
||||
* Print JSON to an output stream.
|
||||
* Print JSON to an output stream. It does not
|
||||
* validate the content.
|
||||
*
|
||||
* @param out The output stream.
|
||||
* @param value The array.
|
||||
@@ -76,7 +83,8 @@ inline std::ostream& operator<<(std::ostream& out, simdjson::SIMDJSON_IMPLEMENTA
|
||||
inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result<simdjson::SIMDJSON_IMPLEMENTATION::ondemand::document_reference>&& x);
|
||||
#endif
|
||||
/**
|
||||
* Print JSON to an output stream.
|
||||
* Print JSON to an output stream. It does not
|
||||
* validate the content.
|
||||
*
|
||||
* @param out The output stream.
|
||||
* @param value The object.
|
||||
|
||||
@@ -54,10 +54,9 @@ simdjson_inline simdjson_result<int64_t> value::get_int64_in_string() noexcept {
|
||||
simdjson_inline simdjson_result<bool> value::get_bool() noexcept {
|
||||
return iter.get_bool();
|
||||
}
|
||||
simdjson_inline bool value::is_null() noexcept {
|
||||
simdjson_inline simdjson_result<bool> value::is_null() noexcept {
|
||||
return iter.is_null();
|
||||
}
|
||||
|
||||
template<> simdjson_inline simdjson_result<array> value::get() noexcept { return get_array(); }
|
||||
template<> simdjson_inline simdjson_result<object> value::get() noexcept { return get_object(); }
|
||||
template<> simdjson_inline simdjson_result<raw_json_string> value::get() noexcept { return get_raw_json_string(); }
|
||||
@@ -311,8 +310,8 @@ simdjson_inline simdjson_result<bool> simdjson_result<SIMDJSON_IMPLEMENTATION::o
|
||||
if (error()) { return error(); }
|
||||
return first.get_bool();
|
||||
}
|
||||
simdjson_inline bool simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::is_null() noexcept {
|
||||
if (error()) { return false; }
|
||||
simdjson_inline simdjson_result<bool> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::is_null() noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.is_null();
|
||||
}
|
||||
|
||||
@@ -404,7 +403,7 @@ simdjson_inline simdjson_result<const char *> simdjson_result<SIMDJSON_IMPLEMENT
|
||||
return first.current_location();
|
||||
}
|
||||
|
||||
simdjson_inline int32_t simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::current_depth() const noexcept {
|
||||
simdjson_inline simdjson_result<int32_t> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::current_depth() const noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.current_depth();
|
||||
}
|
||||
|
||||
@@ -150,11 +150,14 @@ public:
|
||||
simdjson_inline simdjson_result<bool> get_bool() noexcept;
|
||||
|
||||
/**
|
||||
* Checks if this JSON value is null.
|
||||
* Checks if this JSON value is null. If and only if the value is
|
||||
* null, then it is consumed (we advance). If we find a token that
|
||||
* begins with 'n' but is not 'null', then an error is returned.
|
||||
*
|
||||
* @returns Whether the value is null.
|
||||
* @returns INCORRECT_TYPE If the JSON value begins with 'n' and is not 'null'.
|
||||
*/
|
||||
simdjson_inline bool is_null() noexcept;
|
||||
simdjson_inline simdjson_result<bool> is_null() noexcept;
|
||||
|
||||
#if SIMDJSON_EXCEPTIONS
|
||||
/**
|
||||
@@ -334,7 +337,9 @@ public:
|
||||
simdjson_inline simdjson_result<value> operator[](const char *key) noexcept;
|
||||
|
||||
/**
|
||||
* Get the type of this JSON value.
|
||||
* Get the type of this JSON value. It does not validate or consume the value.
|
||||
* E.g., you must still call "is_null()" to check that a value is null even if
|
||||
* "type()" returns json_type::null.
|
||||
*
|
||||
* NOTE: If you're only expecting a value to be one type (a typical case), it's generally
|
||||
* better to just call .get_double, .get_string, etc. and check for INCORRECT_TYPE (or just
|
||||
@@ -583,7 +588,7 @@ public:
|
||||
simdjson_inline simdjson_result<std::string_view> get_string() noexcept;
|
||||
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string> get_raw_json_string() noexcept;
|
||||
simdjson_inline simdjson_result<bool> get_bool() noexcept;
|
||||
simdjson_inline bool is_null() noexcept;
|
||||
simdjson_inline simdjson_result<bool> is_null() noexcept;
|
||||
|
||||
template<typename T> simdjson_inline simdjson_result<T> get() noexcept;
|
||||
|
||||
@@ -676,7 +681,7 @@ public:
|
||||
/** @copydoc simdjson_inline simdjson_result<const char *> current_location() noexcept */
|
||||
simdjson_inline simdjson_result<const char *> current_location() noexcept;
|
||||
/** @copydoc simdjson_inline int32_t current_depth() const noexcept */
|
||||
simdjson_inline int32_t current_depth() const noexcept;
|
||||
simdjson_inline simdjson_result<int32_t> current_depth() const noexcept;
|
||||
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> at_pointer(std::string_view json_pointer) noexcept;
|
||||
};
|
||||
|
||||
|
||||
@@ -468,8 +468,11 @@ simdjson_warn_unused simdjson_inline simdjson_result<bool> value_iterator::parse
|
||||
if (error) { return incorrect_type_error("Not a boolean"); }
|
||||
return simdjson_result<bool>(!not_true);
|
||||
}
|
||||
simdjson_inline bool value_iterator::parse_null(const uint8_t *json) const noexcept {
|
||||
return !atomparsing::str4ncmp(json, "null") && jsoncharutils::is_structural_or_whitespace(json[4]);
|
||||
simdjson_warn_unused simdjson_inline simdjson_result<bool> value_iterator::parse_null(const uint8_t *json) const noexcept {
|
||||
bool is_null_string = !atomparsing::str4ncmp(json, "null") && jsoncharutils::is_structural_or_whitespace(json[4]);
|
||||
// if we start with 'n', we must be a null
|
||||
if(!is_null_string && json[0]=='n') { return incorrect_type_error("Not a null but starts with n"); }
|
||||
return is_null_string;
|
||||
}
|
||||
|
||||
simdjson_warn_unused simdjson_inline simdjson_result<std::string_view> value_iterator::get_string() noexcept {
|
||||
@@ -516,10 +519,11 @@ simdjson_warn_unused simdjson_inline simdjson_result<bool> value_iterator::get_b
|
||||
if(result.error() == SUCCESS) { advance_non_root_scalar("bool"); }
|
||||
return result;
|
||||
}
|
||||
simdjson_inline bool value_iterator::is_null() noexcept {
|
||||
auto result = parse_null(peek_non_root_scalar("null"));
|
||||
if(result) { advance_non_root_scalar("null"); }
|
||||
return result;
|
||||
simdjson_inline simdjson_result<bool> value_iterator::is_null() noexcept {
|
||||
bool is_null_value;
|
||||
SIMDJSON_TRY(parse_null(peek_non_root_scalar("null")).get(is_null_value));
|
||||
if(is_null_value) { advance_non_root_scalar("null"); }
|
||||
return is_null_value;
|
||||
}
|
||||
simdjson_inline bool value_iterator::is_negative() noexcept {
|
||||
return numberparsing::is_negative(peek_non_root_scalar("numbersign"));
|
||||
|
||||
@@ -289,7 +289,7 @@ public:
|
||||
simdjson_warn_unused simdjson_inline simdjson_result<double> get_double() noexcept;
|
||||
simdjson_warn_unused simdjson_inline simdjson_result<double> get_double_in_string() noexcept;
|
||||
simdjson_warn_unused simdjson_inline simdjson_result<bool> get_bool() noexcept;
|
||||
simdjson_inline bool is_null() noexcept;
|
||||
simdjson_warn_unused simdjson_inline simdjson_result<bool> is_null() noexcept;
|
||||
simdjson_warn_unused simdjson_inline bool is_negative() noexcept;
|
||||
simdjson_warn_unused simdjson_inline simdjson_result<bool> is_integer() noexcept;
|
||||
simdjson_warn_unused simdjson_inline simdjson_result<number_type> get_number_type() noexcept;
|
||||
@@ -350,7 +350,7 @@ protected:
|
||||
inline std::string to_string() const noexcept;
|
||||
simdjson_inline value_iterator(json_iterator *json_iter, depth_t depth, token_position start_index) noexcept;
|
||||
|
||||
simdjson_inline bool parse_null(const uint8_t *json) const noexcept;
|
||||
simdjson_inline simdjson_result<bool> parse_null(const uint8_t *json) const noexcept;
|
||||
simdjson_inline simdjson_result<bool> parse_bool(const uint8_t *json) const noexcept;
|
||||
simdjson_inline const uint8_t *peek_start() const noexcept;
|
||||
simdjson_inline uint32_t peek_start_length() const noexcept;
|
||||
|
||||
@@ -17,7 +17,9 @@ simdjson_inline tape_ref::tape_ref(const dom::document *_doc, size_t _json_index
|
||||
simdjson_inline bool tape_ref::is_document_root() const noexcept {
|
||||
return json_index == 1; // should we ever change the structure of the tape, this should get updated.
|
||||
}
|
||||
|
||||
simdjson_inline bool tape_ref::usable() const noexcept {
|
||||
return doc != nullptr; // when the document pointer is null, this tape_ref is uninitialized (should not be accessed).
|
||||
}
|
||||
// Some value types have a specific on-tape word value. It can be faster
|
||||
// to check the type by doing a word-to-word comparison instead of extracting the
|
||||
// most significant 8 bits.
|
||||
|
||||
@@ -38,6 +38,7 @@ public:
|
||||
simdjson_inline const char * get_c_str() const noexcept;
|
||||
inline std::string_view get_string_view() const noexcept;
|
||||
simdjson_inline bool is_document_root() const noexcept;
|
||||
simdjson_inline bool usable() const noexcept;
|
||||
|
||||
/** The document this element references. */
|
||||
const dom::document *doc;
|
||||
|
||||
@@ -4,22 +4,22 @@
|
||||
#define SIMDJSON_SIMDJSON_VERSION_H
|
||||
|
||||
/** The version of simdjson being used (major.minor.revision) */
|
||||
#define SIMDJSON_VERSION 2.2.3
|
||||
#define SIMDJSON_VERSION 3.0.1
|
||||
|
||||
namespace simdjson {
|
||||
enum {
|
||||
/**
|
||||
* The major version (MAJOR.minor.revision) of simdjson being used.
|
||||
*/
|
||||
SIMDJSON_VERSION_MAJOR = 2,
|
||||
SIMDJSON_VERSION_MAJOR = 3,
|
||||
/**
|
||||
* The minor version (major.MINOR.revision) of simdjson being used.
|
||||
*/
|
||||
SIMDJSON_VERSION_MINOR = 2,
|
||||
SIMDJSON_VERSION_MINOR = 0,
|
||||
/**
|
||||
* The revision (major.minor.REVISION) of simdjson being used.
|
||||
*/
|
||||
SIMDJSON_VERSION_REVISION = 3
|
||||
SIMDJSON_VERSION_REVISION = 1
|
||||
};
|
||||
} // namespace simdjson
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* auto-generated on 2022-10-02 16:25:39 -0400. Do not edit! */
|
||||
/* auto-generated on 2022-11-23 10:31:42 -0500. Do not edit! */
|
||||
/* begin file src/simdjson.cpp */
|
||||
#include "simdjson.h"
|
||||
|
||||
@@ -868,9 +868,9 @@ inline char *format_buffer(char *buf, int len, int decimal_exponent,
|
||||
|
||||
std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));
|
||||
// Make it look like a floating-point number (#362, #378)
|
||||
// buf[n + 0] = '.';
|
||||
// buf[n + 1] = '0';
|
||||
return buf + (static_cast<size_t>(n));
|
||||
buf[n + 0] = '.';
|
||||
buf[n + 1] = '0';
|
||||
return buf + (static_cast<size_t>(n)) + 2;
|
||||
}
|
||||
|
||||
if (0 < n && n <= max_exp) {
|
||||
@@ -933,10 +933,8 @@ char *to_chars(char *first, const char *last, double value) {
|
||||
{
|
||||
*first++ = '0';
|
||||
// Make it look like a floating-point number (#362, #378)
|
||||
if(negative) {
|
||||
*first++ = '.';
|
||||
*first++ = '0';
|
||||
}
|
||||
*first++ = '.';
|
||||
*first++ = '0';
|
||||
return first;
|
||||
}
|
||||
// Compute v = buffer * 10^decimal_exponent.
|
||||
|
||||
+119
-48
@@ -1,4 +1,4 @@
|
||||
/* auto-generated on 2022-10-02 16:25:39 -0400. Do not edit! */
|
||||
/* auto-generated on 2022-11-23 10:31:42 -0500. Do not edit! */
|
||||
/* begin file include/simdjson.h */
|
||||
#ifndef SIMDJSON_H
|
||||
#define SIMDJSON_H
|
||||
@@ -43,22 +43,22 @@
|
||||
#define SIMDJSON_SIMDJSON_VERSION_H
|
||||
|
||||
/** The version of simdjson being used (major.minor.revision) */
|
||||
#define SIMDJSON_VERSION 2.2.3
|
||||
#define SIMDJSON_VERSION 3.0.1
|
||||
|
||||
namespace simdjson {
|
||||
enum {
|
||||
/**
|
||||
* The major version (MAJOR.minor.revision) of simdjson being used.
|
||||
*/
|
||||
SIMDJSON_VERSION_MAJOR = 2,
|
||||
SIMDJSON_VERSION_MAJOR = 3,
|
||||
/**
|
||||
* The minor version (major.MINOR.revision) of simdjson being used.
|
||||
*/
|
||||
SIMDJSON_VERSION_MINOR = 2,
|
||||
SIMDJSON_VERSION_MINOR = 0,
|
||||
/**
|
||||
* The revision (major.minor.REVISION) of simdjson being used.
|
||||
*/
|
||||
SIMDJSON_VERSION_REVISION = 3
|
||||
SIMDJSON_VERSION_REVISION = 1
|
||||
};
|
||||
} // namespace simdjson
|
||||
|
||||
@@ -2253,6 +2253,13 @@ namespace std {
|
||||
# define simdjson_fallthrough do {} while (0) /* fallthrough */
|
||||
#endif // simdjson_fallthrough
|
||||
|
||||
|
||||
#if SIMDJSON_DEVELOPMENT_CHECKS
|
||||
#define SIMDJSON_DEVELOPMENT_ASSERT(expr) do { assert ((expr)); } while (0)
|
||||
#else
|
||||
#define SIMDJSON_DEVELOPMENT_ASSERT(expr) do { } while (0)
|
||||
#endif
|
||||
|
||||
#endif // SIMDJSON_COMMON_DEFS_H
|
||||
/* end file include/simdjson/common_defs.h */
|
||||
|
||||
@@ -4048,6 +4055,7 @@ public:
|
||||
simdjson_inline const char * get_c_str() const noexcept;
|
||||
inline std::string_view get_string_view() const noexcept;
|
||||
simdjson_inline bool is_document_root() const noexcept;
|
||||
simdjson_inline bool usable() const noexcept;
|
||||
|
||||
/** The document this element references. */
|
||||
const dom::document *doc;
|
||||
@@ -4533,6 +4541,9 @@ public:
|
||||
/** @overload parse(const uint8_t *buf, size_t len, bool realloc_if_needed) */
|
||||
simdjson_inline simdjson_result<element> parse(const padded_string &s) & noexcept;
|
||||
simdjson_inline simdjson_result<element> parse(const padded_string &s) && =delete;
|
||||
/** @overload parse(const uint8_t *buf, size_t len, bool realloc_if_needed) */
|
||||
simdjson_inline simdjson_result<element> parse(const padded_string_view &v) & noexcept;
|
||||
simdjson_inline simdjson_result<element> parse(const padded_string_view &v) && =delete;
|
||||
|
||||
/** @private We do not want to allow implicit conversion from C string to std::string. */
|
||||
simdjson_inline simdjson_result<element> parse(const char *buf) noexcept = delete;
|
||||
@@ -6844,18 +6855,23 @@ namespace dom {
|
||||
simdjson_inline array::array() noexcept : tape{} {}
|
||||
simdjson_inline array::array(const internal::tape_ref &_tape) noexcept : tape{_tape} {}
|
||||
inline array::iterator array::begin() const noexcept {
|
||||
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
|
||||
return internal::tape_ref(tape.doc, tape.json_index + 1);
|
||||
}
|
||||
inline array::iterator array::end() const noexcept {
|
||||
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
|
||||
return internal::tape_ref(tape.doc, tape.after_element() - 1);
|
||||
}
|
||||
inline size_t array::size() const noexcept {
|
||||
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
|
||||
return tape.scope_count();
|
||||
}
|
||||
inline size_t array::number_of_slots() const noexcept {
|
||||
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
|
||||
return tape.matching_brace_index() - tape.json_index;
|
||||
}
|
||||
inline simdjson_result<element> array::at_pointer(std::string_view json_pointer) const noexcept {
|
||||
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
|
||||
if(json_pointer.empty()) { // an empty string means that we return the current node
|
||||
return element(this->tape); // copy the current node
|
||||
} else if(json_pointer[0] != '/') { // otherwise there is an error
|
||||
@@ -6896,6 +6912,7 @@ inline simdjson_result<element> array::at_pointer(std::string_view json_pointer)
|
||||
}
|
||||
|
||||
inline simdjson_result<element> array::at(size_t index) const noexcept {
|
||||
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
|
||||
size_t i=0;
|
||||
for (auto element : *this) {
|
||||
if (i == index) { return element; }
|
||||
@@ -7130,11 +7147,13 @@ simdjson_inline element::element() noexcept : tape{} {}
|
||||
simdjson_inline element::element(const internal::tape_ref &_tape) noexcept : tape{_tape} { }
|
||||
|
||||
inline element_type element::type() const noexcept {
|
||||
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
|
||||
auto tape_type = tape.tape_ref_type();
|
||||
return tape_type == internal::tape_type::FALSE_VALUE ? element_type::BOOL : static_cast<element_type>(tape_type);
|
||||
}
|
||||
|
||||
inline simdjson_result<bool> element::get_bool() const noexcept {
|
||||
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
|
||||
if(tape.is_true()) {
|
||||
return true;
|
||||
} else if(tape.is_false()) {
|
||||
@@ -7143,6 +7162,7 @@ inline simdjson_result<bool> element::get_bool() const noexcept {
|
||||
return INCORRECT_TYPE;
|
||||
}
|
||||
inline simdjson_result<const char *> element::get_c_str() const noexcept {
|
||||
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
|
||||
switch (tape.tape_ref_type()) {
|
||||
case internal::tape_type::STRING: {
|
||||
return tape.get_c_str();
|
||||
@@ -7152,6 +7172,7 @@ inline simdjson_result<const char *> element::get_c_str() const noexcept {
|
||||
}
|
||||
}
|
||||
inline simdjson_result<size_t> element::get_string_length() const noexcept {
|
||||
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
|
||||
switch (tape.tape_ref_type()) {
|
||||
case internal::tape_type::STRING: {
|
||||
return tape.get_string_length();
|
||||
@@ -7161,6 +7182,7 @@ inline simdjson_result<size_t> element::get_string_length() const noexcept {
|
||||
}
|
||||
}
|
||||
inline simdjson_result<std::string_view> element::get_string() const noexcept {
|
||||
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
|
||||
switch (tape.tape_ref_type()) {
|
||||
case internal::tape_type::STRING:
|
||||
return tape.get_string_view();
|
||||
@@ -7169,6 +7191,7 @@ inline simdjson_result<std::string_view> element::get_string() const noexcept {
|
||||
}
|
||||
}
|
||||
inline simdjson_result<uint64_t> element::get_uint64() const noexcept {
|
||||
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
|
||||
if(simdjson_unlikely(!tape.is_uint64())) { // branch rarely taken
|
||||
if(tape.is_int64()) {
|
||||
int64_t result = tape.next_tape_value<int64_t>();
|
||||
@@ -7182,6 +7205,7 @@ inline simdjson_result<uint64_t> element::get_uint64() const noexcept {
|
||||
return tape.next_tape_value<int64_t>();
|
||||
}
|
||||
inline simdjson_result<int64_t> element::get_int64() const noexcept {
|
||||
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
|
||||
if(simdjson_unlikely(!tape.is_int64())) { // branch rarely taken
|
||||
if(tape.is_uint64()) {
|
||||
uint64_t result = tape.next_tape_value<uint64_t>();
|
||||
@@ -7196,6 +7220,7 @@ inline simdjson_result<int64_t> element::get_int64() const noexcept {
|
||||
return tape.next_tape_value<int64_t>();
|
||||
}
|
||||
inline simdjson_result<double> element::get_double() const noexcept {
|
||||
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
|
||||
// Performance considerations:
|
||||
// 1. Querying tape_ref_type() implies doing a shift, it is fast to just do a straight
|
||||
// comparison.
|
||||
@@ -7217,6 +7242,7 @@ inline simdjson_result<double> element::get_double() const noexcept {
|
||||
return tape.next_tape_value<double>();
|
||||
}
|
||||
inline simdjson_result<array> element::get_array() const noexcept {
|
||||
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
|
||||
switch (tape.tape_ref_type()) {
|
||||
case internal::tape_type::START_ARRAY:
|
||||
return array(tape);
|
||||
@@ -7225,6 +7251,7 @@ inline simdjson_result<array> element::get_array() const noexcept {
|
||||
}
|
||||
}
|
||||
inline simdjson_result<object> element::get_object() const noexcept {
|
||||
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
|
||||
switch (tape.tape_ref_type()) {
|
||||
case internal::tape_type::START_OBJECT:
|
||||
return object(tape);
|
||||
@@ -7304,6 +7331,7 @@ inline simdjson_result<element> element::operator[](const char *key) const noexc
|
||||
}
|
||||
|
||||
inline simdjson_result<element> element::at_pointer(std::string_view json_pointer) const noexcept {
|
||||
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
|
||||
switch (tape.tape_ref_type()) {
|
||||
case internal::tape_type::START_OBJECT:
|
||||
return object(tape).at_pointer(json_pointer);
|
||||
@@ -7339,6 +7367,7 @@ inline simdjson_result<element> element::at_key_case_insensitive(std::string_vie
|
||||
}
|
||||
|
||||
inline bool element::dump_raw_tape(std::ostream &out) const noexcept {
|
||||
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
|
||||
return tape.doc->dump_raw_tape(out);
|
||||
}
|
||||
|
||||
@@ -7946,12 +7975,15 @@ namespace dom {
|
||||
simdjson_inline object::object() noexcept : tape{} {}
|
||||
simdjson_inline object::object(const internal::tape_ref &_tape) noexcept : tape{_tape} { }
|
||||
inline object::iterator object::begin() const noexcept {
|
||||
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
|
||||
return internal::tape_ref(tape.doc, tape.json_index + 1);
|
||||
}
|
||||
inline object::iterator object::end() const noexcept {
|
||||
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
|
||||
return internal::tape_ref(tape.doc, tape.after_element() - 1);
|
||||
}
|
||||
inline size_t object::size() const noexcept {
|
||||
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
|
||||
return tape.scope_count();
|
||||
}
|
||||
|
||||
@@ -7962,6 +7994,7 @@ inline simdjson_result<element> object::operator[](const char *key) const noexce
|
||||
return at_key(key);
|
||||
}
|
||||
inline simdjson_result<element> object::at_pointer(std::string_view json_pointer) const noexcept {
|
||||
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
|
||||
if(json_pointer.empty()) { // an empty string means that we return the current node
|
||||
return element(this->tape); // copy the current node
|
||||
} else if(json_pointer[0] != '/') { // otherwise there is an error
|
||||
@@ -8767,6 +8800,9 @@ simdjson_inline simdjson_result<element> parser::parse(const std::string &s) & n
|
||||
simdjson_inline simdjson_result<element> parser::parse(const padded_string &s) & noexcept {
|
||||
return parse(s.data(), s.length(), false);
|
||||
}
|
||||
simdjson_inline simdjson_result<element> parser::parse(const padded_string_view &v) & noexcept {
|
||||
return parse(v.data(), v.length(), false);
|
||||
}
|
||||
|
||||
inline simdjson_result<document_stream> parser::parse_many(const uint8_t *buf, size_t len, size_t batch_size) noexcept {
|
||||
if(batch_size < MINIMAL_BATCH_SIZE) { batch_size = MINIMAL_BATCH_SIZE; }
|
||||
@@ -8873,7 +8909,9 @@ simdjson_inline tape_ref::tape_ref(const dom::document *_doc, size_t _json_index
|
||||
simdjson_inline bool tape_ref::is_document_root() const noexcept {
|
||||
return json_index == 1; // should we ever change the structure of the tape, this should get updated.
|
||||
}
|
||||
|
||||
simdjson_inline bool tape_ref::usable() const noexcept {
|
||||
return doc != nullptr; // when the document pointer is null, this tape_ref is uninitialized (should not be accessed).
|
||||
}
|
||||
// Some value types have a specific on-tape word value. It can be faster
|
||||
// to check the type by doing a word-to-word comparison instead of extracting the
|
||||
// most significant 8 bits.
|
||||
@@ -23792,7 +23830,7 @@ public:
|
||||
simdjson_warn_unused simdjson_inline simdjson_result<double> get_double() noexcept;
|
||||
simdjson_warn_unused simdjson_inline simdjson_result<double> get_double_in_string() noexcept;
|
||||
simdjson_warn_unused simdjson_inline simdjson_result<bool> get_bool() noexcept;
|
||||
simdjson_inline bool is_null() noexcept;
|
||||
simdjson_warn_unused simdjson_inline simdjson_result<bool> is_null() noexcept;
|
||||
simdjson_warn_unused simdjson_inline bool is_negative() noexcept;
|
||||
simdjson_warn_unused simdjson_inline simdjson_result<bool> is_integer() noexcept;
|
||||
simdjson_warn_unused simdjson_inline simdjson_result<number_type> get_number_type() noexcept;
|
||||
@@ -23853,7 +23891,7 @@ protected:
|
||||
inline std::string to_string() const noexcept;
|
||||
simdjson_inline value_iterator(json_iterator *json_iter, depth_t depth, token_position start_index) noexcept;
|
||||
|
||||
simdjson_inline bool parse_null(const uint8_t *json) const noexcept;
|
||||
simdjson_inline simdjson_result<bool> parse_null(const uint8_t *json) const noexcept;
|
||||
simdjson_inline simdjson_result<bool> parse_bool(const uint8_t *json) const noexcept;
|
||||
simdjson_inline const uint8_t *peek_start() const noexcept;
|
||||
simdjson_inline uint32_t peek_start_length() const noexcept;
|
||||
@@ -24454,11 +24492,14 @@ public:
|
||||
simdjson_inline simdjson_result<value> get_value() noexcept;
|
||||
|
||||
/**
|
||||
* Checks if this JSON value is null.
|
||||
* Checks if this JSON value is null. If and only if the value is
|
||||
* null, then it is consumed (we advance). If we find a token that
|
||||
* begins with 'n' but is not 'null', then an error is returned.
|
||||
*
|
||||
* @returns Whether the value is null.
|
||||
* @returns INCORRECT_TYPE If the JSON value begins with 'n' and is not 'null'.
|
||||
*/
|
||||
simdjson_inline bool is_null() noexcept;
|
||||
simdjson_inline simdjson_result<bool> is_null() noexcept;
|
||||
|
||||
/**
|
||||
* Get this value as the given type.
|
||||
@@ -24691,7 +24732,9 @@ public:
|
||||
simdjson_inline simdjson_result<value> operator[](const char *key) & noexcept;
|
||||
|
||||
/**
|
||||
* Get the type of this JSON value.
|
||||
* Get the type of this JSON value. It does not validate or consume the value.
|
||||
* E.g., you must still call "is_null()" to check that a value is null even if
|
||||
* "type()" returns json_type::null.
|
||||
*
|
||||
* NOTE: If you're only expecting a value to be one type (a typical case), it's generally
|
||||
* better to just call .get_double, .get_string, etc. and check for INCORRECT_TYPE (or just
|
||||
@@ -24923,7 +24966,7 @@ public:
|
||||
simdjson_inline simdjson_result<bool> get_bool() noexcept;
|
||||
simdjson_inline simdjson_result<value> get_value() noexcept;
|
||||
|
||||
simdjson_inline bool is_null() noexcept;
|
||||
simdjson_inline simdjson_result<bool> is_null() noexcept;
|
||||
simdjson_inline simdjson_result<std::string_view> raw_json() noexcept;
|
||||
simdjson_inline operator document&() const noexcept;
|
||||
|
||||
@@ -24988,7 +25031,7 @@ public:
|
||||
simdjson_inline simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::raw_json_string> get_raw_json_string() noexcept;
|
||||
simdjson_inline simdjson_result<bool> get_bool() noexcept;
|
||||
simdjson_inline simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::value> get_value() noexcept;
|
||||
simdjson_inline bool is_null() noexcept;
|
||||
simdjson_inline simdjson_result<bool> is_null() noexcept;
|
||||
|
||||
template<typename T> simdjson_inline simdjson_result<T> get() & noexcept;
|
||||
template<typename T> simdjson_inline simdjson_result<T> get() && noexcept;
|
||||
@@ -25055,7 +25098,7 @@ public:
|
||||
simdjson_inline simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::raw_json_string> get_raw_json_string() noexcept;
|
||||
simdjson_inline simdjson_result<bool> get_bool() noexcept;
|
||||
simdjson_inline simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::value> get_value() noexcept;
|
||||
simdjson_inline bool is_null() noexcept;
|
||||
simdjson_inline simdjson_result<bool> is_null() noexcept;
|
||||
|
||||
#if SIMDJSON_EXCEPTIONS
|
||||
simdjson_inline operator SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::array() & noexcept(false);
|
||||
@@ -25082,8 +25125,8 @@ public:
|
||||
simdjson_inline simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::json_type> type() noexcept;
|
||||
simdjson_inline simdjson_result<bool> is_scalar() noexcept;
|
||||
simdjson_inline simdjson_result<const char *> current_location() noexcept;
|
||||
simdjson_inline int32_t current_depth() const noexcept;
|
||||
simdjson_inline bool is_negative() noexcept;
|
||||
simdjson_inline simdjson_result<int32_t> current_depth() const noexcept;
|
||||
simdjson_inline simdjson_result<bool> is_negative() noexcept;
|
||||
simdjson_inline simdjson_result<bool> is_integer() noexcept;
|
||||
simdjson_inline simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::number_type> get_number_type() noexcept;
|
||||
simdjson_inline simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::number> get_number() noexcept;
|
||||
@@ -25248,11 +25291,14 @@ public:
|
||||
simdjson_inline simdjson_result<bool> get_bool() noexcept;
|
||||
|
||||
/**
|
||||
* Checks if this JSON value is null.
|
||||
* Checks if this JSON value is null. If and only if the value is
|
||||
* null, then it is consumed (we advance). If we find a token that
|
||||
* begins with 'n' but is not 'null', then an error is returned.
|
||||
*
|
||||
* @returns Whether the value is null.
|
||||
* @returns INCORRECT_TYPE If the JSON value begins with 'n' and is not 'null'.
|
||||
*/
|
||||
simdjson_inline bool is_null() noexcept;
|
||||
simdjson_inline simdjson_result<bool> is_null() noexcept;
|
||||
|
||||
#if SIMDJSON_EXCEPTIONS
|
||||
/**
|
||||
@@ -25432,7 +25478,9 @@ public:
|
||||
simdjson_inline simdjson_result<value> operator[](const char *key) noexcept;
|
||||
|
||||
/**
|
||||
* Get the type of this JSON value.
|
||||
* Get the type of this JSON value. It does not validate or consume the value.
|
||||
* E.g., you must still call "is_null()" to check that a value is null even if
|
||||
* "type()" returns json_type::null.
|
||||
*
|
||||
* NOTE: If you're only expecting a value to be one type (a typical case), it's generally
|
||||
* better to just call .get_double, .get_string, etc. and check for INCORRECT_TYPE (or just
|
||||
@@ -25681,7 +25729,7 @@ public:
|
||||
simdjson_inline simdjson_result<std::string_view> get_string() noexcept;
|
||||
simdjson_inline simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::raw_json_string> get_raw_json_string() noexcept;
|
||||
simdjson_inline simdjson_result<bool> get_bool() noexcept;
|
||||
simdjson_inline bool is_null() noexcept;
|
||||
simdjson_inline simdjson_result<bool> is_null() noexcept;
|
||||
|
||||
template<typename T> simdjson_inline simdjson_result<T> get() noexcept;
|
||||
|
||||
@@ -25774,7 +25822,7 @@ public:
|
||||
/** @copydoc simdjson_inline simdjson_result<const char *> current_location() noexcept */
|
||||
simdjson_inline simdjson_result<const char *> current_location() noexcept;
|
||||
/** @copydoc simdjson_inline int32_t current_depth() const noexcept */
|
||||
simdjson_inline int32_t current_depth() const noexcept;
|
||||
simdjson_inline simdjson_result<int32_t> current_depth() const noexcept;
|
||||
simdjson_inline simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::value> at_pointer(std::string_view json_pointer) noexcept;
|
||||
};
|
||||
|
||||
@@ -26315,13 +26363,22 @@ public:
|
||||
/** The maximum capacity of this parser (the largest document it is allowed to process). */
|
||||
simdjson_inline size_t max_capacity() const noexcept;
|
||||
simdjson_inline void set_max_capacity(size_t max_capacity) noexcept;
|
||||
/** The maximum depth of this parser (the most deeply nested objects and arrays it can process). */
|
||||
/**
|
||||
* The maximum depth of this parser (the most deeply nested objects and arrays it can process).
|
||||
* This parameter is only relevant when the macro SIMDJSON_DEVELOPMENT_CHECKS is set to true.
|
||||
* The document's instance current_depth() method should be used to monitor the parsing
|
||||
* depth and limit it if desired.
|
||||
*/
|
||||
simdjson_inline size_t max_depth() const noexcept;
|
||||
|
||||
/**
|
||||
* Ensure this parser has enough memory to process JSON documents up to `capacity` bytes in length
|
||||
* and `max_depth` depth.
|
||||
*
|
||||
* The max_depth parameter is only relevant when the macro SIMDJSON_DEVELOPMENT_CHECKS is set to true.
|
||||
* The document's instance current_depth() method should be used to monitor the parsing
|
||||
* depth and limit it if desired.
|
||||
*
|
||||
* @param capacity The new capacity.
|
||||
* @param max_depth The new max_depth. Defaults to DEFAULT_MAX_DEPTH.
|
||||
* @return The error, if there is one.
|
||||
@@ -26725,23 +26782,27 @@ public:
|
||||
namespace simdjson {
|
||||
/**
|
||||
* Create a string-view instance out of a document instance. The string-view instance
|
||||
* contains JSON text that is suitable to be parsed as JSON again.
|
||||
* contains JSON text that is suitable to be parsed as JSON again. It does not
|
||||
* validate the content.
|
||||
*/
|
||||
inline simdjson_result<std::string_view> to_json_string(SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::document& x) noexcept;
|
||||
/**
|
||||
* Create a string-view instance out of a value instance. The string-view instance
|
||||
* contains JSON text that is suitable to be parsed as JSON again. The value must
|
||||
* not have been accessed previously.
|
||||
* not have been accessed previously. It does not
|
||||
* validate the content.
|
||||
*/
|
||||
inline simdjson_result<std::string_view> to_json_string(SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::value& x) noexcept;
|
||||
/**
|
||||
* Create a string-view instance out of an object instance. The string-view instance
|
||||
* contains JSON text that is suitable to be parsed as JSON again.
|
||||
* contains JSON text that is suitable to be parsed as JSON again. It does not
|
||||
* validate the content.
|
||||
*/
|
||||
inline simdjson_result<std::string_view> to_json_string(SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::object& x) noexcept;
|
||||
/**
|
||||
* Create a string-view instance out of an array instance. The string-view instance
|
||||
* contains JSON text that is suitable to be parsed as JSON again.
|
||||
* contains JSON text that is suitable to be parsed as JSON again. It does not
|
||||
* validate the content.
|
||||
*/
|
||||
inline simdjson_result<std::string_view> to_json_string(SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::array& x) noexcept;
|
||||
inline simdjson_result<std::string_view> to_json_string(simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::document> x);
|
||||
@@ -26760,7 +26821,8 @@ inline simdjson_result<std::string_view> to_json_string(simdjson_result<SIMDJSON
|
||||
namespace simdjson { namespace SIMDJSON_BUILTIN_IMPLEMENTATION { namespace ondemand {
|
||||
|
||||
/**
|
||||
* Print JSON to an output stream.
|
||||
* Print JSON to an output stream. It does not
|
||||
* validate the content.
|
||||
*
|
||||
* @param out The output stream.
|
||||
* @param value The element.
|
||||
@@ -26771,7 +26833,8 @@ inline std::ostream& operator<<(std::ostream& out, simdjson::SIMDJSON_BUILTIN_IM
|
||||
inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result<simdjson::SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::value> x);
|
||||
#endif
|
||||
/**
|
||||
* Print JSON to an output stream.
|
||||
* Print JSON to an output stream. It does not
|
||||
* validate the content.
|
||||
*
|
||||
* @param out The output stream.
|
||||
* @param value The array.
|
||||
@@ -26782,7 +26845,8 @@ inline std::ostream& operator<<(std::ostream& out, simdjson::SIMDJSON_BUILTIN_IM
|
||||
inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result<simdjson::SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::array> x);
|
||||
#endif
|
||||
/**
|
||||
* Print JSON to an output stream.
|
||||
* Print JSON to an output stream. It does not
|
||||
* validate the content.
|
||||
*
|
||||
* @param out The output stream.
|
||||
* @param value The array.
|
||||
@@ -26797,7 +26861,8 @@ inline std::ostream& operator<<(std::ostream& out, simdjson::SIMDJSON_BUILTIN_IM
|
||||
inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result<simdjson::SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::document_reference>&& x);
|
||||
#endif
|
||||
/**
|
||||
* Print JSON to an output stream.
|
||||
* Print JSON to an output stream. It does not
|
||||
* validate the content.
|
||||
*
|
||||
* @param out The output stream.
|
||||
* @param value The object.
|
||||
@@ -27775,6 +27840,7 @@ simdjson_inline void json_iterator::reenter_child(token_position position, depth
|
||||
SIMDJSON_ASSUME(_depth == child_depth - 1);
|
||||
#if SIMDJSON_DEVELOPMENT_CHECKS
|
||||
#ifndef SIMDJSON_CLANG_VISUAL_STUDIO
|
||||
SIMDJSON_ASSUME(size_t(child_depth) < parser->max_depth());
|
||||
SIMDJSON_ASSUME(position >= parser->start_positions[child_depth]);
|
||||
#endif
|
||||
#endif
|
||||
@@ -27785,11 +27851,13 @@ simdjson_inline void json_iterator::reenter_child(token_position position, depth
|
||||
#if SIMDJSON_DEVELOPMENT_CHECKS
|
||||
|
||||
simdjson_inline token_position json_iterator::start_position(depth_t depth) const noexcept {
|
||||
return parser->start_positions[depth];
|
||||
SIMDJSON_ASSUME(size_t(depth) < parser->max_depth());
|
||||
return size_t(depth) < parser->max_depth() ? parser->start_positions[depth] : 0;
|
||||
}
|
||||
|
||||
simdjson_inline void json_iterator::set_start_position(depth_t depth, token_position position) noexcept {
|
||||
parser->start_positions[depth] = position;
|
||||
SIMDJSON_ASSUME(size_t(depth) < parser->max_depth());
|
||||
if(size_t(depth) < parser->max_depth()) { parser->start_positions[depth] = position; }
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -28301,8 +28369,11 @@ simdjson_warn_unused simdjson_inline simdjson_result<bool> value_iterator::parse
|
||||
if (error) { return incorrect_type_error("Not a boolean"); }
|
||||
return simdjson_result<bool>(!not_true);
|
||||
}
|
||||
simdjson_inline bool value_iterator::parse_null(const uint8_t *json) const noexcept {
|
||||
return !atomparsing::str4ncmp(json, "null") && jsoncharutils::is_structural_or_whitespace(json[4]);
|
||||
simdjson_warn_unused simdjson_inline simdjson_result<bool> value_iterator::parse_null(const uint8_t *json) const noexcept {
|
||||
bool is_null_string = !atomparsing::str4ncmp(json, "null") && jsoncharutils::is_structural_or_whitespace(json[4]);
|
||||
// if we start with 'n', we must be a null
|
||||
if(!is_null_string && json[0]=='n') { return incorrect_type_error("Not a null but starts with n"); }
|
||||
return is_null_string;
|
||||
}
|
||||
|
||||
simdjson_warn_unused simdjson_inline simdjson_result<std::string_view> value_iterator::get_string() noexcept {
|
||||
@@ -28349,10 +28420,11 @@ simdjson_warn_unused simdjson_inline simdjson_result<bool> value_iterator::get_b
|
||||
if(result.error() == SUCCESS) { advance_non_root_scalar("bool"); }
|
||||
return result;
|
||||
}
|
||||
simdjson_inline bool value_iterator::is_null() noexcept {
|
||||
auto result = parse_null(peek_non_root_scalar("null"));
|
||||
if(result) { advance_non_root_scalar("null"); }
|
||||
return result;
|
||||
simdjson_inline simdjson_result<bool> value_iterator::is_null() noexcept {
|
||||
bool is_null_value;
|
||||
SIMDJSON_TRY(parse_null(peek_non_root_scalar("null")).get(is_null_value));
|
||||
if(is_null_value) { advance_non_root_scalar("null"); }
|
||||
return is_null_value;
|
||||
}
|
||||
simdjson_inline bool value_iterator::is_negative() noexcept {
|
||||
return numberparsing::is_negative(peek_non_root_scalar("numbersign"));
|
||||
@@ -29337,7 +29409,7 @@ simdjson_inline simdjson_result<raw_json_string> document::get_raw_json_string()
|
||||
simdjson_inline simdjson_result<bool> document::get_bool() noexcept {
|
||||
return get_root_value_iterator().get_root_bool();
|
||||
}
|
||||
simdjson_inline bool document::is_null() noexcept {
|
||||
simdjson_inline simdjson_result<bool> document::is_null() noexcept {
|
||||
return get_root_value_iterator().is_root_null();
|
||||
}
|
||||
|
||||
@@ -29597,7 +29669,7 @@ simdjson_inline simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::value
|
||||
if (error()) { return error(); }
|
||||
return first.get_value();
|
||||
}
|
||||
simdjson_inline bool simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::document>::is_null() noexcept {
|
||||
simdjson_inline simdjson_result<bool> simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::document>::is_null() noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.is_null();
|
||||
}
|
||||
@@ -29747,7 +29819,7 @@ simdjson_inline simdjson_result<std::string_view> document_reference::get_string
|
||||
simdjson_inline simdjson_result<raw_json_string> document_reference::get_raw_json_string() noexcept { return doc->get_raw_json_string(); }
|
||||
simdjson_inline simdjson_result<bool> document_reference::get_bool() noexcept { return doc->get_bool(); }
|
||||
simdjson_inline simdjson_result<value> document_reference::get_value() noexcept { return doc->get_value(); }
|
||||
simdjson_inline bool document_reference::is_null() noexcept { return doc->is_null(); }
|
||||
simdjson_inline simdjson_result<bool> document_reference::is_null() noexcept { return doc->is_null(); }
|
||||
|
||||
#if SIMDJSON_EXCEPTIONS
|
||||
simdjson_inline document_reference::operator array() & noexcept(false) { return array(*doc); }
|
||||
@@ -29879,7 +29951,7 @@ simdjson_inline simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::value
|
||||
if (error()) { return error(); }
|
||||
return first.get_value();
|
||||
}
|
||||
simdjson_inline bool simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::document_reference>::is_null() noexcept {
|
||||
simdjson_inline simdjson_result<bool> simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::document_reference>::is_null() noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.is_null();
|
||||
}
|
||||
@@ -29891,7 +29963,7 @@ simdjson_inline simdjson_result<bool> simdjson_result<SIMDJSON_BUILTIN_IMPLEMENT
|
||||
if (error()) { return error(); }
|
||||
return first.is_scalar();
|
||||
}
|
||||
simdjson_inline bool simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::document_reference>::is_negative() noexcept {
|
||||
simdjson_inline simdjson_result<bool> simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::document_reference>::is_negative() noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.is_negative();
|
||||
}
|
||||
@@ -30021,10 +30093,9 @@ simdjson_inline simdjson_result<int64_t> value::get_int64_in_string() noexcept {
|
||||
simdjson_inline simdjson_result<bool> value::get_bool() noexcept {
|
||||
return iter.get_bool();
|
||||
}
|
||||
simdjson_inline bool value::is_null() noexcept {
|
||||
simdjson_inline simdjson_result<bool> value::is_null() noexcept {
|
||||
return iter.is_null();
|
||||
}
|
||||
|
||||
template<> simdjson_inline simdjson_result<array> value::get() noexcept { return get_array(); }
|
||||
template<> simdjson_inline simdjson_result<object> value::get() noexcept { return get_object(); }
|
||||
template<> simdjson_inline simdjson_result<raw_json_string> value::get() noexcept { return get_raw_json_string(); }
|
||||
@@ -30278,8 +30349,8 @@ simdjson_inline simdjson_result<bool> simdjson_result<SIMDJSON_BUILTIN_IMPLEMENT
|
||||
if (error()) { return error(); }
|
||||
return first.get_bool();
|
||||
}
|
||||
simdjson_inline bool simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::value>::is_null() noexcept {
|
||||
if (error()) { return false; }
|
||||
simdjson_inline simdjson_result<bool> simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::value>::is_null() noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.is_null();
|
||||
}
|
||||
|
||||
@@ -30371,7 +30442,7 @@ simdjson_inline simdjson_result<const char *> simdjson_result<SIMDJSON_BUILTIN_I
|
||||
return first.current_location();
|
||||
}
|
||||
|
||||
simdjson_inline int32_t simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::value>::current_depth() const noexcept {
|
||||
simdjson_inline simdjson_result<int32_t> simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::value>::current_depth() const noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.current_depth();
|
||||
}
|
||||
|
||||
+5
-7
@@ -860,9 +860,9 @@ inline char *format_buffer(char *buf, int len, int decimal_exponent,
|
||||
|
||||
std::memset(buf + k, '0', static_cast<size_t>(n) - static_cast<size_t>(k));
|
||||
// Make it look like a floating-point number (#362, #378)
|
||||
// buf[n + 0] = '.';
|
||||
// buf[n + 1] = '0';
|
||||
return buf + (static_cast<size_t>(n));
|
||||
buf[n + 0] = '.';
|
||||
buf[n + 1] = '0';
|
||||
return buf + (static_cast<size_t>(n)) + 2;
|
||||
}
|
||||
|
||||
if (0 < n && n <= max_exp) {
|
||||
@@ -925,10 +925,8 @@ char *to_chars(char *first, const char *last, double value) {
|
||||
{
|
||||
*first++ = '0';
|
||||
// Make it look like a floating-point number (#362, #378)
|
||||
if(negative) {
|
||||
*first++ = '.';
|
||||
*first++ = '0';
|
||||
}
|
||||
*first++ = '.';
|
||||
*first++ = '0';
|
||||
return first;
|
||||
}
|
||||
// Compute v = buffer * 10^decimal_exponent.
|
||||
|
||||
@@ -160,7 +160,11 @@ namespace ondemand_treewalk {
|
||||
cout << element.get_bool();
|
||||
break;
|
||||
case ondemand::json_type::null:
|
||||
cout << "null";
|
||||
// We check that the value is indeed null
|
||||
// otherwise: an error is thrown.
|
||||
if(element.is_null()) {
|
||||
cout << "null";
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,7 +119,9 @@ namespace error_tests {
|
||||
SUBTEST("simdjson_result<ondemand::value>", test_ondemand_doc(json, [&](auto doc) {
|
||||
simdjson_result<ondemand::value> val = doc["val"];
|
||||
// Get everything that can fail in both forward and backwards order
|
||||
ASSERT_EQUAL( val.is_null(), false );
|
||||
bool is_null_value;
|
||||
ASSERT_SUCCESS( val.is_null().get(is_null_value) );
|
||||
ASSERT_EQUAL( is_null_value, false );
|
||||
ASSERT_ERROR( val.get_array(), INCORRECT_TYPE );
|
||||
ASSERT_ERROR( val.get_string(), INCORRECT_TYPE );
|
||||
ASSERT_ERROR( val.get_double(), INCORRECT_TYPE );
|
||||
@@ -131,15 +133,18 @@ namespace error_tests {
|
||||
ASSERT_ERROR( val.get_double(), INCORRECT_TYPE );
|
||||
ASSERT_ERROR( val.get_string(), INCORRECT_TYPE );
|
||||
ASSERT_ERROR( val.get_array(), INCORRECT_TYPE );
|
||||
ASSERT_EQUAL( val.is_null(), false );
|
||||
ASSERT_SUCCESS( val.get_bool() );
|
||||
ASSERT_SUCCESS( val.is_null().get(is_null_value) );
|
||||
ASSERT_EQUAL( is_null_value, false );
|
||||
TEST_SUCCEED();
|
||||
}));
|
||||
SUBTEST("ondemand::value", test_ondemand_doc(json, [&](auto doc) {
|
||||
ondemand::value val;
|
||||
ASSERT_SUCCESS( doc["val"].get(val) );
|
||||
// Get everything that can fail in both forward and backwards order
|
||||
ASSERT_EQUAL( val.is_null(), false );
|
||||
bool is_null_value;
|
||||
ASSERT_SUCCESS( val.is_null().get(is_null_value) );
|
||||
ASSERT_EQUAL( is_null_value, false );
|
||||
ASSERT_ERROR( val.get_array(), INCORRECT_TYPE );
|
||||
ASSERT_ERROR( val.get_string(), INCORRECT_TYPE );
|
||||
ASSERT_ERROR( val.get_double(), INCORRECT_TYPE );
|
||||
@@ -151,14 +156,17 @@ namespace error_tests {
|
||||
ASSERT_ERROR( val.get_double(), INCORRECT_TYPE );
|
||||
ASSERT_ERROR( val.get_string(), INCORRECT_TYPE );
|
||||
ASSERT_ERROR( val.get_array(), INCORRECT_TYPE );
|
||||
ASSERT_EQUAL( val.is_null(), false );
|
||||
ASSERT_SUCCESS( val.get_bool() );
|
||||
ASSERT_SUCCESS( val.is_null().get(is_null_value) );
|
||||
ASSERT_EQUAL( is_null_value, false );
|
||||
TEST_SUCCEED();
|
||||
}));
|
||||
json = R"(true)"_padded;
|
||||
SUBTEST("simdjson_result<ondemand::document>", test_ondemand_doc(json, [&](simdjson_result<ondemand::document> val) {
|
||||
// Get everything that can fail in both forward and backwards order
|
||||
ASSERT_EQUAL( val.is_null(), false );
|
||||
bool is_null_value;
|
||||
ASSERT_SUCCESS( val.is_null().get(is_null_value) );
|
||||
ASSERT_EQUAL( is_null_value, false );
|
||||
ASSERT_ERROR( val.get_array(), INCORRECT_TYPE );
|
||||
ASSERT_ERROR( val.get_string(), INCORRECT_TYPE );
|
||||
ASSERT_ERROR( val.get_double(), INCORRECT_TYPE );
|
||||
@@ -170,14 +178,17 @@ namespace error_tests {
|
||||
ASSERT_ERROR( val.get_double(), INCORRECT_TYPE );
|
||||
ASSERT_ERROR( val.get_string(), INCORRECT_TYPE );
|
||||
ASSERT_ERROR( val.get_array(), INCORRECT_TYPE );
|
||||
ASSERT_EQUAL( val.is_null(), false );
|
||||
ASSERT_SUCCESS( val.get_bool());
|
||||
ASSERT_SUCCESS( val.is_null().get(is_null_value) );
|
||||
ASSERT_EQUAL( is_null_value, false );
|
||||
TEST_SUCCEED();
|
||||
}));
|
||||
SUBTEST("ondemand::document", test_ondemand_doc(json, [&](auto doc) {
|
||||
ondemand::document val;
|
||||
ASSERT_SUCCESS( std::move(doc).get(val) ); // Get everything that can fail in both forward and backwards order
|
||||
ASSERT_EQUAL( val.is_null(), false );
|
||||
bool is_null_value;
|
||||
ASSERT_SUCCESS( val.is_null().get(is_null_value) );
|
||||
ASSERT_EQUAL( is_null_value, false );
|
||||
ASSERT_ERROR( val.get_array(), INCORRECT_TYPE );
|
||||
ASSERT_ERROR( val.get_string(), INCORRECT_TYPE );
|
||||
ASSERT_ERROR( val.get_double(), INCORRECT_TYPE );
|
||||
@@ -189,8 +200,9 @@ namespace error_tests {
|
||||
ASSERT_ERROR( val.get_double(), INCORRECT_TYPE );
|
||||
ASSERT_ERROR( val.get_string(), INCORRECT_TYPE );
|
||||
ASSERT_ERROR( val.get_array(), INCORRECT_TYPE );
|
||||
ASSERT_EQUAL( val.is_null(), false );
|
||||
ASSERT_SUCCESS( val.get_bool() );
|
||||
ASSERT_SUCCESS( val.is_null().get(is_null_value) );
|
||||
ASSERT_EQUAL( is_null_value, false );
|
||||
TEST_SUCCEED();
|
||||
}));
|
||||
|
||||
@@ -216,13 +228,16 @@ namespace error_tests {
|
||||
ASSERT_ERROR( val.get_string(), INCORRECT_TYPE );
|
||||
ASSERT_ERROR( val.get_array(), INCORRECT_TYPE );
|
||||
ASSERT_ERROR( val.get_bool(), INCORRECT_TYPE );
|
||||
ASSERT_EQUAL( val.is_null(), true );
|
||||
bool is_null_value;
|
||||
ASSERT_SUCCESS( val.is_null().get(is_null_value) );
|
||||
ASSERT_EQUAL( is_null_value, true );
|
||||
TEST_SUCCEED();
|
||||
}));
|
||||
SUBTEST("ondemand::value", test_ondemand_doc(json, [&](auto doc) {
|
||||
ondemand::value val;
|
||||
ASSERT_SUCCESS( doc["val"].get(val) );
|
||||
// Get everything that can fail in both forward and backwards order
|
||||
|
||||
ASSERT_ERROR( val.get_bool(), INCORRECT_TYPE );
|
||||
ASSERT_ERROR( val.get_array(), INCORRECT_TYPE );
|
||||
ASSERT_ERROR( val.get_string(), INCORRECT_TYPE );
|
||||
@@ -236,7 +251,9 @@ namespace error_tests {
|
||||
ASSERT_ERROR( val.get_string(), INCORRECT_TYPE );
|
||||
ASSERT_ERROR( val.get_array(), INCORRECT_TYPE );
|
||||
ASSERT_ERROR( val.get_bool(), INCORRECT_TYPE );
|
||||
ASSERT_EQUAL( val.is_null(), true );
|
||||
bool is_null_value;
|
||||
ASSERT_SUCCESS( val.is_null().get(is_null_value) );
|
||||
ASSERT_EQUAL( is_null_value, true );
|
||||
TEST_SUCCEED();
|
||||
}));
|
||||
json = R"(null)"_padded;
|
||||
@@ -255,7 +272,9 @@ namespace error_tests {
|
||||
ASSERT_ERROR( val.get_string(), INCORRECT_TYPE );
|
||||
ASSERT_ERROR( val.get_array(), INCORRECT_TYPE );
|
||||
ASSERT_ERROR( val.get_bool(), INCORRECT_TYPE );
|
||||
ASSERT_EQUAL( val.is_null(), true );
|
||||
bool is_null_value;
|
||||
ASSERT_SUCCESS( val.is_null().get(is_null_value) );
|
||||
ASSERT_EQUAL( is_null_value, true );
|
||||
TEST_SUCCEED();
|
||||
}));
|
||||
SUBTEST("ondemand::document", test_ondemand_doc(json, [&](auto doc) {
|
||||
@@ -274,7 +293,9 @@ namespace error_tests {
|
||||
ASSERT_ERROR( val.get_string(), INCORRECT_TYPE );
|
||||
ASSERT_ERROR( val.get_array(), INCORRECT_TYPE );
|
||||
ASSERT_ERROR( val.get_bool(), INCORRECT_TYPE );
|
||||
ASSERT_EQUAL( val.is_null(), true );
|
||||
bool is_null_value;
|
||||
ASSERT_SUCCESS( val.is_null().get(is_null_value) );
|
||||
ASSERT_EQUAL( is_null_value, true );
|
||||
TEST_SUCCEED();
|
||||
}));
|
||||
TEST_SUCCEED();
|
||||
|
||||
@@ -71,7 +71,7 @@ namespace json_pointer_tests {
|
||||
ASSERT_SUCCESS(val.get_bool().error());
|
||||
break;
|
||||
case ondemand::json_type::null:
|
||||
ASSERT_TRUE(val.is_null());
|
||||
ASSERT_SUCCESS(val.is_null().error());
|
||||
break;
|
||||
default:
|
||||
TEST_FAIL("unexpected type");
|
||||
|
||||
@@ -271,7 +271,9 @@ namespace misc_tests {
|
||||
ASSERT_SUCCESS(global.get(global_object));
|
||||
ondemand::value shadowable;
|
||||
ASSERT_SUCCESS(global_object["shadowable"].get(shadowable));
|
||||
ASSERT_TRUE(!shadowable.is_null());
|
||||
bool is_null_value;
|
||||
ASSERT_SUCCESS(shadowable.is_null().get(is_null_value));
|
||||
ASSERT_TRUE(!is_null_value);
|
||||
ondemand::value badvalue;
|
||||
auto error = global_object["writable"].get(badvalue);
|
||||
if(error == SUCCESS) {
|
||||
|
||||
@@ -87,7 +87,11 @@ void recursive_print_json(ondemand::value element) {
|
||||
cout << element.get_bool();
|
||||
break;
|
||||
case ondemand::json_type::null:
|
||||
cout << "null";
|
||||
// we check that the value is indeed null
|
||||
// otherwise: an error is thrown.
|
||||
if(element.is_null()) {
|
||||
cout << "null";
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -166,7 +170,11 @@ void recursive_print_json_breakline(ondemand::value element) {
|
||||
cout << element.get_bool();
|
||||
break;
|
||||
case ondemand::json_type::null:
|
||||
cout << "null";
|
||||
// We check that the value is indeed null
|
||||
// otherwise: an error is thrown.
|
||||
if(element.is_null()) {
|
||||
cout << "null";
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -206,11 +206,15 @@ namespace scalar_tests {
|
||||
SUBTEST("ondemand::document", test_ondemand_doc(json, [&](auto doc_result) {
|
||||
ondemand::document doc;
|
||||
ASSERT_SUCCESS( std::move(doc_result).get(doc) );
|
||||
ASSERT_EQUAL( doc.is_null(), true );
|
||||
bool is_null_value;
|
||||
ASSERT_SUCCESS( doc.is_null().get(is_null_value) );
|
||||
ASSERT_EQUAL( is_null_value, true );
|
||||
return true;
|
||||
}));
|
||||
SUBTEST("simdjson_result<ondemand::document>", test_ondemand_doc(json, [&](auto doc_result) {
|
||||
ASSERT_EQUAL( doc_result.is_null(), true );
|
||||
bool is_null_value;
|
||||
ASSERT_SUCCESS( doc_result.is_null().get(is_null_value) );
|
||||
ASSERT_EQUAL( is_null_value, true );
|
||||
return true;
|
||||
}));
|
||||
json = "[null]"_padded;
|
||||
@@ -219,7 +223,9 @@ namespace scalar_tests {
|
||||
for (auto value_result : doc_result) {
|
||||
ondemand::value value;
|
||||
ASSERT_SUCCESS( value_result.get(value) );
|
||||
ASSERT_EQUAL( value.is_null(), true );
|
||||
bool is_null_value;
|
||||
ASSERT_SUCCESS( value.is_null().get(is_null_value) );
|
||||
ASSERT_EQUAL( is_null_value, true );
|
||||
count++;
|
||||
}
|
||||
ASSERT_EQUAL( count, 1 );
|
||||
@@ -228,7 +234,9 @@ namespace scalar_tests {
|
||||
SUBTEST("simdjson_result<ondemand::value>", test_ondemand_doc(json, [&](auto doc_result) {
|
||||
int count = 0;
|
||||
for (auto value_result : doc_result) {
|
||||
ASSERT_EQUAL( value_result.is_null(), true );
|
||||
bool is_null_value;
|
||||
ASSERT_SUCCESS( value_result.is_null().get(is_null_value) );
|
||||
ASSERT_EQUAL( is_null_value, true );
|
||||
count++;
|
||||
}
|
||||
ASSERT_EQUAL( count, 1 );
|
||||
|
||||
@@ -63,7 +63,19 @@ int main(int argc, const char *argv[]) {
|
||||
simdjson::ondemand::document doc;
|
||||
error = parser.iterate(docdata).get(doc);
|
||||
if(error != simdjson::SUCCESS) { std::cout << error << std::endl; return EXIT_FAILURE; }
|
||||
// This locates the document and captures a string_view instance, it does
|
||||
// not validate the document:
|
||||
std::cout << doc;
|
||||
// check if there is more content
|
||||
const char * endofstream;
|
||||
if(doc.current_location().get(endofstream) == simdjson::SUCCESS) {
|
||||
// there is more content !
|
||||
// let us find what it is:
|
||||
size_t len = docdata.data() + docdata.size() - endofstream;
|
||||
std::string_view content{endofstream, len};
|
||||
std::cerr << "\nThere is leftover content: '" << content << "'" << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
simdjson::dom::parser parser;
|
||||
|
||||
Reference in New Issue
Block a user