Compare commits

...

7 Commits

Author SHA1 Message Date
Daniel Lemire d520062f8e Bumping API 2022-10-06 11:50:33 -04:00
Daniel Lemire db08d78ed0 Documents better the type method and makes is_null return an error condition in some instances (#1909) 2022-10-06 11:47:40 -04:00
Daniel Lemire 46292b8d4b Update basics.md 2022-10-05 08:50:52 -04:00
Tyson Andre 46241287c6 Check for trailing tokens in json2msgpack ondemand benchmark (#1908)
Related to #1904

Users of the simdjson library will see json2msgpack as an available
example of how to recursively process json with the ondemand parser,
and checking for trailing tokens in a document is one part of json validation.

These checks shouldn't affect benchmark results performance.
The benchmark is run on the 631KB twitter.json file.
2022-10-05 08:49:09 -04:00
Daniel Lemire 137cb14bcc Documenting how one can check for the end of the document. (#1907) 2022-10-04 20:23:52 -04:00
Daniel Lemire 5e6be3ed7a Minor fix (documentation and safety) regarding max. depth in ondemand. (#1906) 2022-10-04 12:24:20 -04:00
Tyson Andre c6ab52eebb [skip ci] Add an .editorconfig for .cpp/.h/.md for whitespace settings (#1901)
Make it less likely to accidentally introduce tabs, trailing whitespace,
carriage returns, non-utf8 in files, or files without trailing newlines.

https://editorconfig.org/ has plugins for various editors/IDEs and is
enabled by default in some IDEs.
2022-10-03 11:14:00 -04:00
27 changed files with 291 additions and 160 deletions
+12
View File
@@ -0,0 +1,12 @@
# https://editorconfig.org/
root = true
# Conservatively avoid changing defaults for other file types, e.g. raw json files for test cases,
# Makefiles, etc.
[*.{cpp,h,md}]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
tab_width = 2
trim_trailing_whitespace = true
+1
View File
@@ -78,6 +78,7 @@
.gitattributes export-ignore .gitattributes export-ignore
.gitignore export-ignore .gitignore export-ignore
.editorconfig export-ignore
# Sources # Sources
*.c text eol=lf diff=c *.c text eol=lf diff=c
-34
View File
@@ -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
View File
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.14)
project( project(
simdjson simdjson
# The version number is modified by tools/release.py # The version number is modified by tools/release.py
VERSION 2.2.3 VERSION 3.0.0
DESCRIPTION "Parsing gigabytes of JSON per second" DESCRIPTION "Parsing gigabytes of JSON per second"
HOMEPAGE_URL "https://simdjson.org/" HOMEPAGE_URL "https://simdjson.org/"
LANGUAGES CXX C LANGUAGES CXX C
@@ -20,8 +20,8 @@ string(
# ---- Options, variables ---- # ---- Options, variables ----
# These version numbers are modified by tools/release.py # These version numbers are modified by tools/release.py
set(SIMDJSON_LIB_VERSION "13.0.0" CACHE STRING "simdjson library version") set(SIMDJSON_LIB_VERSION "14.0.0" CACHE STRING "simdjson library version")
set(SIMDJSON_LIB_SOVERSION "13" CACHE STRING "simdjson library soversion") set(SIMDJSON_LIB_SOVERSION "14" CACHE STRING "simdjson library soversion")
option(SIMDJSON_ENABLE_THREADS "Link with thread support" ON) option(SIMDJSON_ENABLE_THREADS "Link with thread support" ON)
+1 -1
View File
@@ -38,7 +38,7 @@ PROJECT_NAME = simdjson
# could be handy for archiving the generated documentation or if some version # could be handy for archiving the generated documentation or if some version
# control system is used. # control system is used.
PROJECT_NUMBER = "2.2.3" PROJECT_NUMBER = "3.0.0"
# Using the PROJECT_BRIEF tag one can provide an optional one line description # 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 # for a project that appears at the top of each page and should give viewer a
+1 -1
View File
@@ -3,7 +3,7 @@
[![Ubuntu 20.04 CI](https://github.com/simdjson/simdjson/workflows/Ubuntu%2020.04%20CI%20(GCC%209)/badge.svg)](https://simdjson.org/plots.html) [![Ubuntu 20.04 CI](https://github.com/simdjson/simdjson/workflows/Ubuntu%2020.04%20CI%20(GCC%209)/badge.svg)](https://simdjson.org/plots.html)
![VS16-CI](https://github.com/simdjson/simdjson/workflows/VS16-CI/badge.svg) ![VS16-CI](https://github.com/simdjson/simdjson/workflows/VS16-CI/badge.svg)
![MinGW64-CI](https://github.com/simdjson/simdjson/workflows/MinGW64-CI/badge.svg) ![MinGW64-CI](https://github.com/simdjson/simdjson/workflows/MinGW64-CI/badge.svg)
[![][license img]][license] [![Doxygen Documentation](https://img.shields.io/badge/docs-doxygen-green.svg)](https://simdjson.org/api/2.0.0/index.html) [![][license img]][license] [![Doxygen Documentation](https://img.shields.io/badge/docs-doxygen-green.svg)](https://simdjson.org/api/3.0.0/index.html)
simdjson : Parsing gigabytes of JSON per second simdjson : Parsing gigabytes of JSON per second
=============================================== ===============================================
+15 -3
View File
@@ -74,18 +74,26 @@ simdjson2msgpack::to_msgpack(const simdjson::padded_string &json,
write_byte(0xc2 + doc.get_bool()); write_byte(0xc2 + doc.get_bool());
break; break;
case simdjson::ondemand::json_type::null: 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; break;
case simdjson::ondemand::json_type::array: case simdjson::ondemand::json_type::array:
case simdjson::ondemand::json_type::object: case simdjson::ondemand::json_type::object:
default: default:
// impossible // impossible
break; SIMDJSON_UNREACHABLE();
} }
} else { } else {
simdjson::ondemand::value val = doc; simdjson::ondemand::value val = doc;
recursive_processor(val); recursive_processor(val);
} }
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)); return std::string_view(reinterpret_cast<char *>(buf), size_t(buff - buf));
} }
@@ -156,7 +164,11 @@ void simdjson2msgpack::recursive_processor(simdjson::ondemand::value element) {
write_byte(0xc2 + element.get_bool()); write_byte(0xc2 + element.get_bool());
break; break;
case simdjson::ondemand::json_type::null: 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; break;
default: default:
SIMDJSON_UNREACHABLE(); SIMDJSON_UNREACHABLE();
+22 -3
View File
@@ -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" 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 * **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 with a known type, and are trying to generically inspect or walk over JSON elements.
`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). 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`. 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++ ```c++
void recursive_print_json(ondemand::value element) { 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(); cout << element.get_bool();
break; break;
case ondemand::json_type::null: 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; break;
} }
} }
@@ -1110,6 +1126,9 @@ for (auto val : doc) {
std::cout << doc.current_location() << std::endl; // Throws OUT_OF_BOUNDS 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 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: are thrown. This can be helpful for users that want to know the current state of iteration during parsing. For example:
@@ -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 { simdjson_inline simdjson_result<bool> document::get_bool() noexcept {
return get_root_value_iterator().get_root_bool(); 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(); 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(); } if (error()) { return error(); }
return first.get_value(); 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(); } if (error()) { return error(); }
return first.is_null(); 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<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<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 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 #if SIMDJSON_EXCEPTIONS
simdjson_inline document_reference::operator array() & noexcept(false) { return array(*doc); } 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(); } if (error()) { return error(); }
return first.get_value(); 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(); } if (error()) { return error(); }
return first.is_null(); return first.is_null();
} }
@@ -648,7 +648,7 @@ simdjson_inline simdjson_result<bool> simdjson_result<SIMDJSON_IMPLEMENTATION::o
if (error()) { return error(); } if (error()) { return error(); }
return first.is_scalar(); 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(); } if (error()) { return error(); }
return first.is_negative(); return first.is_negative();
} }
+13 -8
View File
@@ -126,11 +126,14 @@ public:
simdjson_inline simdjson_result<value> get_value() noexcept; 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 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. * Get this value as the given type.
@@ -363,7 +366,9 @@ public:
simdjson_inline simdjson_result<value> operator[](const char *key) & noexcept; 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 * 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 * 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<bool> get_bool() noexcept;
simdjson_inline simdjson_result<value> get_value() 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 simdjson_result<std::string_view> raw_json() noexcept;
simdjson_inline operator document&() const 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<SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string> get_raw_json_string() noexcept;
simdjson_inline simdjson_result<bool> get_bool() noexcept; simdjson_inline simdjson_result<bool> get_bool() noexcept;
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> get_value() 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;
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<SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string> get_raw_json_string() noexcept;
simdjson_inline simdjson_result<bool> get_bool() noexcept; simdjson_inline simdjson_result<bool> get_bool() noexcept;
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value> get_value() 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 #if SIMDJSON_EXCEPTIONS
simdjson_inline operator SIMDJSON_IMPLEMENTATION::ondemand::array() & noexcept(false); 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<SIMDJSON_IMPLEMENTATION::ondemand::json_type> type() noexcept;
simdjson_inline simdjson_result<bool> is_scalar() noexcept; simdjson_inline simdjson_result<bool> is_scalar() noexcept;
simdjson_inline simdjson_result<const char *> current_location() noexcept; simdjson_inline simdjson_result<const char *> current_location() noexcept;
simdjson_inline int32_t current_depth() const noexcept; simdjson_inline simdjson_result<int32_t> current_depth() const noexcept;
simdjson_inline bool is_negative() noexcept; simdjson_inline simdjson_result<bool> is_negative() noexcept;
simdjson_inline simdjson_result<bool> is_integer() 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_type> get_number_type() noexcept;
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::number> get_number() 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); SIMDJSON_ASSUME(_depth == child_depth - 1);
#if SIMDJSON_DEVELOPMENT_CHECKS #if SIMDJSON_DEVELOPMENT_CHECKS
#ifndef SIMDJSON_CLANG_VISUAL_STUDIO #ifndef SIMDJSON_CLANG_VISUAL_STUDIO
SIMDJSON_ASSUME(size_t(child_depth) < parser->max_depth());
SIMDJSON_ASSUME(position >= parser->start_positions[child_depth]); SIMDJSON_ASSUME(position >= parser->start_positions[child_depth]);
#endif #endif
#endif #endif
@@ -335,11 +336,13 @@ simdjson_inline void json_iterator::reenter_child(token_position position, depth
#if SIMDJSON_DEVELOPMENT_CHECKS #if SIMDJSON_DEVELOPMENT_CHECKS
simdjson_inline token_position json_iterator::start_position(depth_t depth) const noexcept { 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 { 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 #endif
+10 -1
View File
@@ -230,13 +230,22 @@ public:
/** The maximum capacity of this parser (the largest document it is allowed to process). */ /** The maximum capacity of this parser (the largest document it is allowed to process). */
simdjson_inline size_t max_capacity() const noexcept; simdjson_inline size_t max_capacity() const noexcept;
simdjson_inline void set_max_capacity(size_t max_capacity) 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; simdjson_inline size_t max_depth() const noexcept;
/** /**
* Ensure this parser has enough memory to process JSON documents up to `capacity` bytes in length * Ensure this parser has enough memory to process JSON documents up to `capacity` bytes in length
* and `max_depth` depth. * 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 capacity The new capacity.
* @param max_depth The new max_depth. Defaults to DEFAULT_MAX_DEPTH. * @param max_depth The new max_depth. Defaults to DEFAULT_MAX_DEPTH.
* @return The error, if there is one. * @return The error, if there is one.
@@ -4,23 +4,27 @@
namespace simdjson { namespace simdjson {
/** /**
* Create a string-view instance out of a document instance. The string-view instance * 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; 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 * 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 * 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; 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 * 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; 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 * 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_IMPLEMENTATION::ondemand::array& x) noexcept;
inline simdjson_result<std::string_view> to_json_string(simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document> x); 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 { 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 out The output stream.
* @param value The element. * @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); inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result<simdjson::SIMDJSON_IMPLEMENTATION::ondemand::value> x);
#endif #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 out The output stream.
* @param value The array. * @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); inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result<simdjson::SIMDJSON_IMPLEMENTATION::ondemand::array> x);
#endif #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 out The output stream.
* @param value The array. * @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); inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result<simdjson::SIMDJSON_IMPLEMENTATION::ondemand::document_reference>&& x);
#endif #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 out The output stream.
* @param value The object. * @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 { simdjson_inline simdjson_result<bool> value::get_bool() noexcept {
return iter.get_bool(); return iter.get_bool();
} }
simdjson_inline bool value::is_null() noexcept { simdjson_inline simdjson_result<bool> value::is_null() noexcept {
return iter.is_null(); return iter.is_null();
} }
template<> simdjson_inline simdjson_result<array> value::get() noexcept { return get_array(); } 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<object> value::get() noexcept { return get_object(); }
template<> simdjson_inline simdjson_result<raw_json_string> value::get() noexcept { return get_raw_json_string(); } 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(); } if (error()) { return error(); }
return first.get_bool(); return first.get_bool();
} }
simdjson_inline bool simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::is_null() noexcept { simdjson_inline simdjson_result<bool> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::is_null() noexcept {
if (error()) { return false; } if (error()) { return error(); }
return first.is_null(); return first.is_null();
} }
@@ -404,7 +403,7 @@ simdjson_inline simdjson_result<const char *> simdjson_result<SIMDJSON_IMPLEMENT
return first.current_location(); 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(); } if (error()) { return error(); }
return first.current_depth(); return first.current_depth();
} }
+10 -5
View File
@@ -150,11 +150,14 @@ public:
simdjson_inline simdjson_result<bool> get_bool() noexcept; 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 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 #if SIMDJSON_EXCEPTIONS
/** /**
@@ -334,7 +337,9 @@ public:
simdjson_inline simdjson_result<value> operator[](const char *key) noexcept; 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 * 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 * 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<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<SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string> get_raw_json_string() noexcept;
simdjson_inline simdjson_result<bool> get_bool() 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; 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 */ /** @copydoc simdjson_inline simdjson_result<const char *> current_location() noexcept */
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 */ /** @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; 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"); } if (error) { return incorrect_type_error("Not a boolean"); }
return simdjson_result<bool>(!not_true); return simdjson_result<bool>(!not_true);
} }
simdjson_inline bool value_iterator::parse_null(const uint8_t *json) const noexcept { simdjson_warn_unused simdjson_inline simdjson_result<bool> value_iterator::parse_null(const uint8_t *json) const noexcept {
return !atomparsing::str4ncmp(json, "null") && jsoncharutils::is_structural_or_whitespace(json[4]); 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 { 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"); } if(result.error() == SUCCESS) { advance_non_root_scalar("bool"); }
return result; return result;
} }
simdjson_inline bool value_iterator::is_null() noexcept { simdjson_inline simdjson_result<bool> value_iterator::is_null() noexcept {
auto result = parse_null(peek_non_root_scalar("null")); bool is_null_value;
if(result) { advance_non_root_scalar("null"); } SIMDJSON_TRY(parse_null(peek_non_root_scalar("null")).get(is_null_value));
return result; if(is_null_value) { advance_non_root_scalar("null"); }
return is_null_value;
} }
simdjson_inline bool value_iterator::is_negative() noexcept { simdjson_inline bool value_iterator::is_negative() noexcept {
return numberparsing::is_negative(peek_non_root_scalar("numbersign")); 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() noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<double> get_double_in_string() 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_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 bool is_negative() noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<bool> is_integer() 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; 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; 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 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 simdjson_result<bool> parse_bool(const uint8_t *json) const noexcept;
simdjson_inline const uint8_t *peek_start() const noexcept; simdjson_inline const uint8_t *peek_start() const noexcept;
simdjson_inline uint32_t peek_start_length() const noexcept; simdjson_inline uint32_t peek_start_length() const noexcept;
+4 -4
View File
@@ -4,22 +4,22 @@
#define SIMDJSON_SIMDJSON_VERSION_H #define SIMDJSON_SIMDJSON_VERSION_H
/** The version of simdjson being used (major.minor.revision) */ /** The version of simdjson being used (major.minor.revision) */
#define SIMDJSON_VERSION 2.2.3 #define SIMDJSON_VERSION 3.0.0
namespace simdjson { namespace simdjson {
enum { enum {
/** /**
* The major version (MAJOR.minor.revision) of simdjson being used. * 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. * 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. * The revision (major.minor.REVISION) of simdjson being used.
*/ */
SIMDJSON_VERSION_REVISION = 3 SIMDJSON_VERSION_REVISION = 0
}; };
} // namespace simdjson } // namespace simdjson
+1 -1
View File
@@ -1,4 +1,4 @@
/* auto-generated on 2022-10-02 16:25:39 -0400. Do not edit! */ /* auto-generated on 2022-10-06 11:47:40 -0400. Do not edit! */
/* begin file src/simdjson.cpp */ /* begin file src/simdjson.cpp */
#include "simdjson.h" #include "simdjson.h"
+80 -47
View File
@@ -1,4 +1,4 @@
/* auto-generated on 2022-10-02 16:25:39 -0400. Do not edit! */ /* auto-generated on 2022-10-06 11:47:40 -0400. Do not edit! */
/* begin file include/simdjson.h */ /* begin file include/simdjson.h */
#ifndef SIMDJSON_H #ifndef SIMDJSON_H
#define SIMDJSON_H #define SIMDJSON_H
@@ -43,22 +43,22 @@
#define SIMDJSON_SIMDJSON_VERSION_H #define SIMDJSON_SIMDJSON_VERSION_H
/** The version of simdjson being used (major.minor.revision) */ /** The version of simdjson being used (major.minor.revision) */
#define SIMDJSON_VERSION 2.2.3 #define SIMDJSON_VERSION 3.0.0
namespace simdjson { namespace simdjson {
enum { enum {
/** /**
* The major version (MAJOR.minor.revision) of simdjson being used. * 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. * 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. * The revision (major.minor.REVISION) of simdjson being used.
*/ */
SIMDJSON_VERSION_REVISION = 3 SIMDJSON_VERSION_REVISION = 0
}; };
} // namespace simdjson } // namespace simdjson
@@ -23792,7 +23792,7 @@ public:
simdjson_warn_unused simdjson_inline simdjson_result<double> get_double() noexcept; 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<double> get_double_in_string() noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<bool> get_bool() 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 bool is_negative() noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<bool> is_integer() 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; simdjson_warn_unused simdjson_inline simdjson_result<number_type> get_number_type() noexcept;
@@ -23853,7 +23853,7 @@ protected:
inline std::string to_string() const noexcept; 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 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 simdjson_result<bool> parse_bool(const uint8_t *json) const noexcept;
simdjson_inline const uint8_t *peek_start() const noexcept; simdjson_inline const uint8_t *peek_start() const noexcept;
simdjson_inline uint32_t peek_start_length() const noexcept; simdjson_inline uint32_t peek_start_length() const noexcept;
@@ -24454,11 +24454,14 @@ public:
simdjson_inline simdjson_result<value> get_value() noexcept; 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 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. * Get this value as the given type.
@@ -24691,7 +24694,9 @@ public:
simdjson_inline simdjson_result<value> operator[](const char *key) & noexcept; 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 * 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 * better to just call .get_double, .get_string, etc. and check for INCORRECT_TYPE (or just
@@ -24923,7 +24928,7 @@ public:
simdjson_inline simdjson_result<bool> get_bool() noexcept; simdjson_inline simdjson_result<bool> get_bool() noexcept;
simdjson_inline simdjson_result<value> get_value() 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 simdjson_result<std::string_view> raw_json() noexcept;
simdjson_inline operator document&() const noexcept; simdjson_inline operator document&() const noexcept;
@@ -24988,7 +24993,7 @@ public:
simdjson_inline simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::raw_json_string> get_raw_json_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 simdjson_result<bool> get_bool() noexcept;
simdjson_inline simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::value> get_value() 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;
template<typename T> simdjson_inline simdjson_result<T> get() && noexcept; template<typename T> simdjson_inline simdjson_result<T> get() && noexcept;
@@ -25055,7 +25060,7 @@ public:
simdjson_inline simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::raw_json_string> get_raw_json_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 simdjson_result<bool> get_bool() noexcept;
simdjson_inline simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::value> get_value() 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 #if SIMDJSON_EXCEPTIONS
simdjson_inline operator SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::array() & noexcept(false); simdjson_inline operator SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::array() & noexcept(false);
@@ -25082,8 +25087,8 @@ public:
simdjson_inline simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::json_type> type() noexcept; simdjson_inline simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::json_type> type() noexcept;
simdjson_inline simdjson_result<bool> is_scalar() noexcept; simdjson_inline simdjson_result<bool> is_scalar() noexcept;
simdjson_inline simdjson_result<const char *> current_location() noexcept; simdjson_inline simdjson_result<const char *> current_location() noexcept;
simdjson_inline int32_t current_depth() const noexcept; simdjson_inline simdjson_result<int32_t> current_depth() const noexcept;
simdjson_inline bool is_negative() noexcept; simdjson_inline simdjson_result<bool> is_negative() noexcept;
simdjson_inline simdjson_result<bool> is_integer() 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_type> get_number_type() noexcept;
simdjson_inline simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::number> get_number() noexcept; simdjson_inline simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::number> get_number() noexcept;
@@ -25248,11 +25253,14 @@ public:
simdjson_inline simdjson_result<bool> get_bool() noexcept; 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 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 #if SIMDJSON_EXCEPTIONS
/** /**
@@ -25432,7 +25440,9 @@ public:
simdjson_inline simdjson_result<value> operator[](const char *key) noexcept; 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 * 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 * better to just call .get_double, .get_string, etc. and check for INCORRECT_TYPE (or just
@@ -25681,7 +25691,7 @@ public:
simdjson_inline simdjson_result<std::string_view> get_string() noexcept; 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<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::raw_json_string> get_raw_json_string() noexcept;
simdjson_inline simdjson_result<bool> get_bool() 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; template<typename T> simdjson_inline simdjson_result<T> get() noexcept;
@@ -25774,7 +25784,7 @@ public:
/** @copydoc simdjson_inline simdjson_result<const char *> current_location() noexcept */ /** @copydoc simdjson_inline simdjson_result<const char *> current_location() noexcept */
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 */ /** @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; simdjson_inline simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::value> at_pointer(std::string_view json_pointer) noexcept;
}; };
@@ -26315,13 +26325,22 @@ public:
/** The maximum capacity of this parser (the largest document it is allowed to process). */ /** The maximum capacity of this parser (the largest document it is allowed to process). */
simdjson_inline size_t max_capacity() const noexcept; simdjson_inline size_t max_capacity() const noexcept;
simdjson_inline void set_max_capacity(size_t max_capacity) 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; simdjson_inline size_t max_depth() const noexcept;
/** /**
* Ensure this parser has enough memory to process JSON documents up to `capacity` bytes in length * Ensure this parser has enough memory to process JSON documents up to `capacity` bytes in length
* and `max_depth` depth. * 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 capacity The new capacity.
* @param max_depth The new max_depth. Defaults to DEFAULT_MAX_DEPTH. * @param max_depth The new max_depth. Defaults to DEFAULT_MAX_DEPTH.
* @return The error, if there is one. * @return The error, if there is one.
@@ -26725,23 +26744,27 @@ public:
namespace simdjson { namespace simdjson {
/** /**
* Create a string-view instance out of a document instance. The string-view instance * 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; 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 * 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 * 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; 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 * 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; 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 * 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_BUILTIN_IMPLEMENTATION::ondemand::array& x) noexcept;
inline simdjson_result<std::string_view> to_json_string(simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::document> x); inline simdjson_result<std::string_view> to_json_string(simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::document> x);
@@ -26760,7 +26783,8 @@ inline simdjson_result<std::string_view> to_json_string(simdjson_result<SIMDJSON
namespace simdjson { namespace SIMDJSON_BUILTIN_IMPLEMENTATION { namespace ondemand { 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 out The output stream.
* @param value The element. * @param value The element.
@@ -26771,7 +26795,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); inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result<simdjson::SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::value> x);
#endif #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 out The output stream.
* @param value The array. * @param value The array.
@@ -26782,7 +26807,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); inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result<simdjson::SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::array> x);
#endif #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 out The output stream.
* @param value The array. * @param value The array.
@@ -26797,7 +26823,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); inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result<simdjson::SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::document_reference>&& x);
#endif #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 out The output stream.
* @param value The object. * @param value The object.
@@ -27775,6 +27802,7 @@ simdjson_inline void json_iterator::reenter_child(token_position position, depth
SIMDJSON_ASSUME(_depth == child_depth - 1); SIMDJSON_ASSUME(_depth == child_depth - 1);
#if SIMDJSON_DEVELOPMENT_CHECKS #if SIMDJSON_DEVELOPMENT_CHECKS
#ifndef SIMDJSON_CLANG_VISUAL_STUDIO #ifndef SIMDJSON_CLANG_VISUAL_STUDIO
SIMDJSON_ASSUME(size_t(child_depth) < parser->max_depth());
SIMDJSON_ASSUME(position >= parser->start_positions[child_depth]); SIMDJSON_ASSUME(position >= parser->start_positions[child_depth]);
#endif #endif
#endif #endif
@@ -27785,11 +27813,13 @@ simdjson_inline void json_iterator::reenter_child(token_position position, depth
#if SIMDJSON_DEVELOPMENT_CHECKS #if SIMDJSON_DEVELOPMENT_CHECKS
simdjson_inline token_position json_iterator::start_position(depth_t depth) const noexcept { 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 { 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 #endif
@@ -28301,8 +28331,11 @@ simdjson_warn_unused simdjson_inline simdjson_result<bool> value_iterator::parse
if (error) { return incorrect_type_error("Not a boolean"); } if (error) { return incorrect_type_error("Not a boolean"); }
return simdjson_result<bool>(!not_true); return simdjson_result<bool>(!not_true);
} }
simdjson_inline bool value_iterator::parse_null(const uint8_t *json) const noexcept { simdjson_warn_unused simdjson_inline simdjson_result<bool> value_iterator::parse_null(const uint8_t *json) const noexcept {
return !atomparsing::str4ncmp(json, "null") && jsoncharutils::is_structural_or_whitespace(json[4]); 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 { simdjson_warn_unused simdjson_inline simdjson_result<std::string_view> value_iterator::get_string() noexcept {
@@ -28349,10 +28382,11 @@ simdjson_warn_unused simdjson_inline simdjson_result<bool> value_iterator::get_b
if(result.error() == SUCCESS) { advance_non_root_scalar("bool"); } if(result.error() == SUCCESS) { advance_non_root_scalar("bool"); }
return result; return result;
} }
simdjson_inline bool value_iterator::is_null() noexcept { simdjson_inline simdjson_result<bool> value_iterator::is_null() noexcept {
auto result = parse_null(peek_non_root_scalar("null")); bool is_null_value;
if(result) { advance_non_root_scalar("null"); } SIMDJSON_TRY(parse_null(peek_non_root_scalar("null")).get(is_null_value));
return result; if(is_null_value) { advance_non_root_scalar("null"); }
return is_null_value;
} }
simdjson_inline bool value_iterator::is_negative() noexcept { simdjson_inline bool value_iterator::is_negative() noexcept {
return numberparsing::is_negative(peek_non_root_scalar("numbersign")); return numberparsing::is_negative(peek_non_root_scalar("numbersign"));
@@ -29337,7 +29371,7 @@ simdjson_inline simdjson_result<raw_json_string> document::get_raw_json_string()
simdjson_inline simdjson_result<bool> document::get_bool() noexcept { simdjson_inline simdjson_result<bool> document::get_bool() noexcept {
return get_root_value_iterator().get_root_bool(); 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(); return get_root_value_iterator().is_root_null();
} }
@@ -29597,7 +29631,7 @@ simdjson_inline simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::value
if (error()) { return error(); } if (error()) { return error(); }
return first.get_value(); 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(); } if (error()) { return error(); }
return first.is_null(); return first.is_null();
} }
@@ -29747,7 +29781,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<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<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 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 #if SIMDJSON_EXCEPTIONS
simdjson_inline document_reference::operator array() & noexcept(false) { return array(*doc); } simdjson_inline document_reference::operator array() & noexcept(false) { return array(*doc); }
@@ -29879,7 +29913,7 @@ simdjson_inline simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::value
if (error()) { return error(); } if (error()) { return error(); }
return first.get_value(); 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(); } if (error()) { return error(); }
return first.is_null(); return first.is_null();
} }
@@ -29891,7 +29925,7 @@ simdjson_inline simdjson_result<bool> simdjson_result<SIMDJSON_BUILTIN_IMPLEMENT
if (error()) { return error(); } if (error()) { return error(); }
return first.is_scalar(); 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(); } if (error()) { return error(); }
return first.is_negative(); return first.is_negative();
} }
@@ -30021,10 +30055,9 @@ simdjson_inline simdjson_result<int64_t> value::get_int64_in_string() noexcept {
simdjson_inline simdjson_result<bool> value::get_bool() noexcept { simdjson_inline simdjson_result<bool> value::get_bool() noexcept {
return iter.get_bool(); return iter.get_bool();
} }
simdjson_inline bool value::is_null() noexcept { simdjson_inline simdjson_result<bool> value::is_null() noexcept {
return iter.is_null(); return iter.is_null();
} }
template<> simdjson_inline simdjson_result<array> value::get() noexcept { return get_array(); } 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<object> value::get() noexcept { return get_object(); }
template<> simdjson_inline simdjson_result<raw_json_string> value::get() noexcept { return get_raw_json_string(); } template<> simdjson_inline simdjson_result<raw_json_string> value::get() noexcept { return get_raw_json_string(); }
@@ -30278,8 +30311,8 @@ simdjson_inline simdjson_result<bool> simdjson_result<SIMDJSON_BUILTIN_IMPLEMENT
if (error()) { return error(); } if (error()) { return error(); }
return first.get_bool(); return first.get_bool();
} }
simdjson_inline bool simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::value>::is_null() noexcept { simdjson_inline simdjson_result<bool> simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::value>::is_null() noexcept {
if (error()) { return false; } if (error()) { return error(); }
return first.is_null(); return first.is_null();
} }
@@ -30371,7 +30404,7 @@ simdjson_inline simdjson_result<const char *> simdjson_result<SIMDJSON_BUILTIN_I
return first.current_location(); 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(); } if (error()) { return error(); }
return first.current_depth(); return first.current_depth();
} }
+5 -1
View File
@@ -160,7 +160,11 @@ namespace ondemand_treewalk {
cout << element.get_bool(); cout << element.get_bool();
break; break;
case ondemand::json_type::null: 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; break;
} }
} }
+33 -12
View File
@@ -119,7 +119,9 @@ namespace error_tests {
SUBTEST("simdjson_result<ondemand::value>", test_ondemand_doc(json, [&](auto doc) { SUBTEST("simdjson_result<ondemand::value>", test_ondemand_doc(json, [&](auto doc) {
simdjson_result<ondemand::value> val = doc["val"]; simdjson_result<ondemand::value> val = doc["val"];
// Get everything that can fail in both forward and backwards order // 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_array(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_string(), INCORRECT_TYPE ); ASSERT_ERROR( val.get_string(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_double(), 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_double(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_string(), INCORRECT_TYPE ); ASSERT_ERROR( val.get_string(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_array(), INCORRECT_TYPE ); ASSERT_ERROR( val.get_array(), INCORRECT_TYPE );
ASSERT_EQUAL( val.is_null(), false );
ASSERT_SUCCESS( val.get_bool() ); ASSERT_SUCCESS( val.get_bool() );
ASSERT_SUCCESS( val.is_null().get(is_null_value) );
ASSERT_EQUAL( is_null_value, false );
TEST_SUCCEED(); TEST_SUCCEED();
})); }));
SUBTEST("ondemand::value", test_ondemand_doc(json, [&](auto doc) { SUBTEST("ondemand::value", test_ondemand_doc(json, [&](auto doc) {
ondemand::value val; ondemand::value val;
ASSERT_SUCCESS( doc["val"].get(val) ); ASSERT_SUCCESS( doc["val"].get(val) );
// Get everything that can fail in both forward and backwards order // 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_array(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_string(), INCORRECT_TYPE ); ASSERT_ERROR( val.get_string(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_double(), 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_double(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_string(), INCORRECT_TYPE ); ASSERT_ERROR( val.get_string(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_array(), INCORRECT_TYPE ); ASSERT_ERROR( val.get_array(), INCORRECT_TYPE );
ASSERT_EQUAL( val.is_null(), false );
ASSERT_SUCCESS( val.get_bool() ); ASSERT_SUCCESS( val.get_bool() );
ASSERT_SUCCESS( val.is_null().get(is_null_value) );
ASSERT_EQUAL( is_null_value, false );
TEST_SUCCEED(); TEST_SUCCEED();
})); }));
json = R"(true)"_padded; json = R"(true)"_padded;
SUBTEST("simdjson_result<ondemand::document>", test_ondemand_doc(json, [&](simdjson_result<ondemand::document> val) { 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 // 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_array(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_string(), INCORRECT_TYPE ); ASSERT_ERROR( val.get_string(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_double(), 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_double(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_string(), INCORRECT_TYPE ); ASSERT_ERROR( val.get_string(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_array(), INCORRECT_TYPE ); ASSERT_ERROR( val.get_array(), INCORRECT_TYPE );
ASSERT_EQUAL( val.is_null(), false );
ASSERT_SUCCESS( val.get_bool()); ASSERT_SUCCESS( val.get_bool());
ASSERT_SUCCESS( val.is_null().get(is_null_value) );
ASSERT_EQUAL( is_null_value, false );
TEST_SUCCEED(); TEST_SUCCEED();
})); }));
SUBTEST("ondemand::document", test_ondemand_doc(json, [&](auto doc) { SUBTEST("ondemand::document", test_ondemand_doc(json, [&](auto doc) {
ondemand::document val; ondemand::document val;
ASSERT_SUCCESS( std::move(doc).get(val) ); // Get everything that can fail in both forward and backwards order 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_array(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_string(), INCORRECT_TYPE ); ASSERT_ERROR( val.get_string(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_double(), 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_double(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_string(), INCORRECT_TYPE ); ASSERT_ERROR( val.get_string(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_array(), INCORRECT_TYPE ); ASSERT_ERROR( val.get_array(), INCORRECT_TYPE );
ASSERT_EQUAL( val.is_null(), false );
ASSERT_SUCCESS( val.get_bool() ); ASSERT_SUCCESS( val.get_bool() );
ASSERT_SUCCESS( val.is_null().get(is_null_value) );
ASSERT_EQUAL( is_null_value, false );
TEST_SUCCEED(); TEST_SUCCEED();
})); }));
@@ -216,13 +228,16 @@ namespace error_tests {
ASSERT_ERROR( val.get_string(), INCORRECT_TYPE ); ASSERT_ERROR( val.get_string(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_array(), INCORRECT_TYPE ); ASSERT_ERROR( val.get_array(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_bool(), 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();
})); }));
SUBTEST("ondemand::value", test_ondemand_doc(json, [&](auto doc) { SUBTEST("ondemand::value", test_ondemand_doc(json, [&](auto doc) {
ondemand::value val; ondemand::value val;
ASSERT_SUCCESS( doc["val"].get(val) ); ASSERT_SUCCESS( doc["val"].get(val) );
// Get everything that can fail in both forward and backwards order // Get everything that can fail in both forward and backwards order
ASSERT_ERROR( val.get_bool(), INCORRECT_TYPE ); ASSERT_ERROR( val.get_bool(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_array(), INCORRECT_TYPE ); ASSERT_ERROR( val.get_array(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_string(), 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_string(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_array(), INCORRECT_TYPE ); ASSERT_ERROR( val.get_array(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_bool(), 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();
})); }));
json = R"(null)"_padded; json = R"(null)"_padded;
@@ -255,7 +272,9 @@ namespace error_tests {
ASSERT_ERROR( val.get_string(), INCORRECT_TYPE ); ASSERT_ERROR( val.get_string(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_array(), INCORRECT_TYPE ); ASSERT_ERROR( val.get_array(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_bool(), 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();
})); }));
SUBTEST("ondemand::document", test_ondemand_doc(json, [&](auto doc) { 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_string(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_array(), INCORRECT_TYPE ); ASSERT_ERROR( val.get_array(), INCORRECT_TYPE );
ASSERT_ERROR( val.get_bool(), 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();
})); }));
TEST_SUCCEED(); TEST_SUCCEED();
@@ -71,7 +71,7 @@ namespace json_pointer_tests {
ASSERT_SUCCESS(val.get_bool().error()); ASSERT_SUCCESS(val.get_bool().error());
break; break;
case ondemand::json_type::null: case ondemand::json_type::null:
ASSERT_TRUE(val.is_null()); ASSERT_SUCCESS(val.is_null().error());
break; break;
default: default:
TEST_FAIL("unexpected type"); TEST_FAIL("unexpected type");
+3 -1
View File
@@ -271,7 +271,9 @@ namespace misc_tests {
ASSERT_SUCCESS(global.get(global_object)); ASSERT_SUCCESS(global.get(global_object));
ondemand::value shadowable; ondemand::value shadowable;
ASSERT_SUCCESS(global_object["shadowable"].get(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; ondemand::value badvalue;
auto error = global_object["writable"].get(badvalue); auto error = global_object["writable"].get(badvalue);
if(error == SUCCESS) { if(error == SUCCESS) {
+10 -2
View File
@@ -87,7 +87,11 @@ void recursive_print_json(ondemand::value element) {
cout << element.get_bool(); cout << element.get_bool();
break; break;
case ondemand::json_type::null: 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; break;
} }
} }
@@ -166,7 +170,11 @@ void recursive_print_json_breakline(ondemand::value element) {
cout << element.get_bool(); cout << element.get_bool();
break; break;
case ondemand::json_type::null: 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; break;
} }
} }
+12 -4
View File
@@ -206,11 +206,15 @@ namespace scalar_tests {
SUBTEST("ondemand::document", test_ondemand_doc(json, [&](auto doc_result) { SUBTEST("ondemand::document", test_ondemand_doc(json, [&](auto doc_result) {
ondemand::document doc; ondemand::document doc;
ASSERT_SUCCESS( std::move(doc_result).get(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; return true;
})); }));
SUBTEST("simdjson_result<ondemand::document>", test_ondemand_doc(json, [&](auto doc_result) { 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; return true;
})); }));
json = "[null]"_padded; json = "[null]"_padded;
@@ -219,7 +223,9 @@ namespace scalar_tests {
for (auto value_result : doc_result) { for (auto value_result : doc_result) {
ondemand::value value; ondemand::value value;
ASSERT_SUCCESS( value_result.get(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++; count++;
} }
ASSERT_EQUAL( count, 1 ); ASSERT_EQUAL( count, 1 );
@@ -228,7 +234,9 @@ namespace scalar_tests {
SUBTEST("simdjson_result<ondemand::value>", test_ondemand_doc(json, [&](auto doc_result) { SUBTEST("simdjson_result<ondemand::value>", test_ondemand_doc(json, [&](auto doc_result) {
int count = 0; int count = 0;
for (auto value_result : doc_result) { 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++; count++;
} }
ASSERT_EQUAL( count, 1 ); ASSERT_EQUAL( count, 1 );
+12
View File
@@ -63,7 +63,19 @@ int main(int argc, const char *argv[]) {
simdjson::ondemand::document doc; simdjson::ondemand::document doc;
error = parser.iterate(docdata).get(doc); error = parser.iterate(docdata).get(doc);
if(error != simdjson::SUCCESS) { std::cout << error << std::endl; return EXIT_FAILURE; } 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; 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; return EXIT_SUCCESS;
} }
simdjson::dom::parser parser; simdjson::dom::parser parser;