Removing the padding.

This commit is contained in:
Daniel Lemire
2021-07-22 17:32:06 -04:00
parent 910686ffa8
commit dc86daa4ec
29 changed files with 221 additions and 212 deletions
+44 -47
View File
@@ -132,25 +132,22 @@ auto json = padded_string::load("twitter.json");
ondemand::document doc = parser.iterate(json); // position a pointer at the beginning of the JSON data
```
Or by creating a padded string (for efficiency reasons, simdjson requires a string with
SIMDJSON_PADDING bytes at the end) and calling `iterate()`:
Or by creating a string and calling `iterate()`:
```c++
ondemand::parser parser;
auto json = "[1,2,3]"_padded; // The _padded suffix creates a simdjson::padded_string instance
std::string json = "[1,2,3]";
ondemand::document doc = parser.iterate(json); // parse a string
```
If you have a buffer of your own with enough padding already (SIMDJSON_PADDING extra bytes allocated), you can use `padded_string_view` to pass it in:
If you have a buffer of your own pass it in:
```c++
ondemand::parser parser;
char json[3+SIMDJSON_PADDING];
strcpy(json, "[1]");
ondemand::document doc = parser.iterate(json, strlen(json), sizeof(json));
const char * json = "[1]";
ondemand::document doc = parser.iterate(json, strlen(json));
```
We recommend against creating many `std::string` or many `std::padding_string` instances in your application to store your JSON data.
Consider reusing the same buffers and limiting memory allocations.
Documents Are Iterators
@@ -242,7 +239,7 @@ support for users who avoid exceptions. See [the simdjson error handling documen
> parsing and writing out the unescaped keys to a string buffer and returning a `std::string_view`
> instance. You should expect a performance penalty when using `unescaped_key()`.
> ```c++
> auto json = R"({"k\u0065y": 1})"_padded;
> std::string json = R"({"k\u0065y": 1})";
> ondemand::parser parser;
> auto doc = parser.iterate(json);
> ondemand::object object = doc.get_object();
@@ -264,7 +261,7 @@ support for users who avoid exceptions. See [the simdjson error handling documen
>
> ```c++
> ondemand::parser parser;
> auto json = R"( { "x": 1, "y": 2 } )"_padded;
> std::string json = R"( { "x": 1, "y": 2 } )";
> auto doc = parser.iterate(json);
> double y = doc.find_field("y"); // The cursor is now after the 2 (at })
> double x = doc.find_field("x"); // This fails, because there are no more fields after "y"
@@ -274,7 +271,7 @@ support for users who avoid exceptions. See [the simdjson error handling documen
>
> ```c++
> ondemand::parser parser;
> auto json = R"( { "x": 1, "y": 2 } )"_padded;
> std::string json = R"( { "x": 1, "y": 2 } )";
> auto doc = parser.iterate(json);
> double y = doc["y"]; // The cursor is now after the 2 (at })
> double x = doc["x"]; // Success: [] loops back around to find "x"
@@ -291,23 +288,23 @@ support for users who avoid exceptions. See [the simdjson error handling documen
* **Output to strings (simdjson 1.0 or better):** Given a document, a value, an array or an object in a JSON document, you can output a JSON string version suitable to be parsed again as JSON content: `simdjson::to_json_string(element)`. A call to `to_json_string` consumes fully the element: if you apply it on a document, the JSON pointer is advanced to the end of the document. The `simdjson::to_json_string` does not allocate memory. The `to_json_string` function should not be confused with retrieving the value of a string instance which are escaped and represented using a lightweight `std::string_view` instance pointing at an internal string buffer inside the parser instance. To illustrate, the first of the following two code segments will print the unescaped string `"test"` complete with the quote whereas the second one will print the escaped content of the string (without the quotes).
> ```C++
> // serialize a JSON to an escaped std::string instance so that it can be parsed again as JSON
> auto silly_json = R"( { "test": "result" } )"_padded;
> std::string silly_json = R"( { "test": "result" } )";
> ondemand::document doc = parser.iterate(silly_json);
> std::cout << simdjson::to_json_string(doc["test"]) << std::endl; // Requires simdjson 1.0 or better
>````
> ```C++
> // retrieves an unescaped string value as a string_view instance
> auto silly_json = R"( { "test": "result" } )"_padded;
> std::string silly_json = R"( { "test": "result" } )";
> ondemand::document doc = parser.iterate(silly_json);
> std::cout << std::string_view(doc["test"]) << std::endl;
>````
You can use `to_json_string` to efficiently extract components of a JSON document to reconstruct a new JSON document, as in the following example:
> ```C++
> auto cars_json = R"( [
> std::string cars_json = R"( [
> { "make": "Toyota", "model": "Camry", "year": 2018, "tire_pressure": [ 40.1, 39.9, 37.7, 40.4 ] },
> { "make": "Kia", "model": "Soul", "year": 2012, "tire_pressure": [ 30.1, 31.0, 28.6, 28.7 ] },
> { "make": "Toyota", "model": "Tercel", "year": 1999, "tire_pressure": [ 29.8, 30.0, 30.2, 30.5 ] }
> ] )"_padded;
> ] )";
> std::vector<std::string_view> arrays;
> // We are going to collect string_view instances which point inside the `cars_json` string
> // and are therefore valid as long as `cars_json` remains in scope.
@@ -338,11 +335,11 @@ The following code illustrates many of the above concepts:
```c++
ondemand::parser parser;
auto cars_json = R"( [
std::string cars_json = R"( [
{ "make": "Toyota", "model": "Camry", "year": 2018, "tire_pressure": [ 40.1, 39.9, 37.7, 40.4 ] },
{ "make": "Kia", "model": "Soul", "year": 2012, "tire_pressure": [ 30.1, 31.0, 28.6, 28.7 ] },
{ "make": "Toyota", "model": "Tercel", "year": 1999, "tire_pressure": [ 29.8, 30.0, 30.2, 30.5 ] }
] )"_padded;
] )";
// Iterating through an array of objects
for (ondemand::object car : parser.iterate(cars_json)) {
@@ -366,10 +363,10 @@ Here is a different example illustrating the same ideas:
```C++
ondemand::parser parser;
auto points_json = R"( [
std::string points_json = R"( [
{ "12345" : {"x":12.34, "y":56.78, "z": 9998877} },
{ "12545" : {"x":11.44, "y":12.78, "z": 11111111} }
] )"_padded;
] )";
// Parse and iterate through an array of objects
for (ondemand::object points : parser.iterate(points_json)) {
@@ -385,9 +382,9 @@ for (ondemand::object points : parser.iterate(points_json)) {
And another one:
```C++
auto abstract_json = R"(
std::string abstract_json = R"(
{ "str" : { "123" : {"abc" : 3.14 } } }
)"_padded;
)";
ondemand::parser parser;
auto doc = parser.iterate(abstract_json);
cout << doc["str"]["123"]["abc"].get_double() << endl; // Prints 3.14
@@ -399,9 +396,9 @@ cout << doc["str"]["123"]["abc"].get_double() << endl; // Prints 3.14
to `get()` which gives you back an error code: e.g.,
```c++
auto abstract_json = R"(
std::string abstract_json = R"(
{ "str" : { "123" : {"abc" : 3.14 } } }
)"_padded;
)";
ondemand::parser parser;
double value;
@@ -417,7 +414,7 @@ aware that the `count_elements` method can be costly since it requires scanning
whole array. You may use it as follows if your document is itself an array:
```C++
auto cars_json = R"( [ 40.1, 39.9, 37.7, 40.4 ] )"_padded;
std::string cars_json = R"( [ 40.1, 39.9, 37.7, 40.4 ] )";
auto doc = parser.iterate(cars_json);
size_t count = doc.count_elements(); // requires simdjson 1.0 or better
std::vector<double> values(count);
@@ -429,7 +426,7 @@ If you access an array inside a document, you can use the `count_elements` metho
You should not let the array instance go out of scope before consuming it after calling the `count_elements` method:
``` C++
ondemand::parser parser;
auto cars_json = R"( { "test":[ { "val1":1, "val2":2 }, { "val1":1, "val2":2 } ] } )"_padded;
std::string cars_json = R"( { "test":[ { "val1":1, "val2":2 }, { "val1":1, "val2":2 } ] } )";
auto doc = parser.iterate(cars_json);
auto test_array = doc.find_field("test").get_array();
size_t count = test_array.count_elements(); // requires simdjson 1.0 or better
@@ -511,7 +508,7 @@ C++17 Support
While the simdjson library can be used in any project using C++ 11 and above, field iteration has special support C++ 17's destructuring syntax. For example:
```c++
padded_string json = R"( { "foo": 1, "bar": 2 } )"_padded;
std::string json = R"( { "foo": 1, "bar": 2 } )";
dom::parser parser;
dom::object object;
auto error = parser.parse(json).get(object);
@@ -525,7 +522,7 @@ For comparison, here is the C++ 11 version of the same code:
```c++
// C++ 11 version for comparison
padded_string json = R"( { "foo": 1, "bar": 2 } )"_padded;
std::string json = R"( { "foo": 1, "bar": 2 } )";
dom::parser parser;
dom::object object;
auto error = parser.parse(json).get(object);
@@ -580,11 +577,11 @@ The simdjson library also supports [JSON pointer](https://tools.ietf.org/html/rf
Consider the following example:
```c++
auto cars_json = R"( [
std::string cars_json = R"( [
{ "make": "Toyota", "model": "Camry", "year": 2018, "tire_pressure": [ 40.1, 39.9, 37.7, 40.4 ] },
{ "make": "Kia", "model": "Soul", "year": 2012, "tire_pressure": [ 30.1, 31.0, 28.6, 28.7 ] },
{ "make": "Toyota", "model": "Tercel", "year": 1999, "tire_pressure": [ 29.8, 30.0, 30.2, 30.5 ] }
] )"_padded;
] )";
ondemand::parser parser;
auto cars = parser.iterate(cars_json);
cout << cars.at_pointer("/0/tire_pressure/1") << endl; // Prints 39.9
@@ -598,11 +595,11 @@ select the value. If your keys contain the characters '/' or '~', they must be e
For multiple JSON pointer queries on a document, one can call `at_pointer` multiple times.
```c++
auto cars_json = R"( [
std::string cars_json = R"( [
{ "make": "Toyota", "model": "Camry", "year": 2018, "tire_pressure": [ 40.1, 39.9, 37.7, 40.4 ] },
{ "make": "Kia", "model": "Soul", "year": 2012, "tire_pressure": [ 30.1, 31.0, 28.6, 28.7 ] },
{ "make": "Toyota", "model": "Tercel", "year": 1999, "tire_pressure": [ 29.8, 30.0, 30.2, 30.5 ] }
] )"_padded;
] )";
ondemand::parser parser;
auto cars = parser.iterate(cars_json);
size_t size = cars.count_elements();
@@ -627,11 +624,11 @@ struct car_type {
make{_make}, model{_model}, year(_year), tire_pressure(_tire_pressure) {}
};
auto cars_json = R"( [
std::string cars_json = R"( [
{ "make": "Toyota", "model": "Camry", "year": 2018, "tire_pressure": [ 40.1, 39.9, 37.7, 40.4 ] },
{ "make": "Kia", "model": "Soul", "year": 2012, "tire_pressure": [ 30.1, 31.0, 28.6, 28.7 ] },
{ "make": "Toyota", "model": "Tercel", "year": 1999, "tire_pressure": [ 29.8, 30.0, 30.2, 30.5 ] }
] )"_padded;
] )";
ondemand::parser parser;
ondemand::document cars;
@@ -667,11 +664,11 @@ for (int i = 0; i < 3; i++) {
Furthermore, `at_pointer` calls `rewind` at the beginning of the call (i.e. the document is not reset after `at_pointer`). Consider the following example,
```c++
auto json = R"( {
std::string json = R"( {
"k0": 27,
"k1": [13,26],
"k2": true
} )"_padded;
} )";
ondemand::parser parser;
auto doc = parser.iterate(json);
std::cout << doc.at_pointer("/k1/1") << std::endl; // Prints 26
@@ -766,11 +763,11 @@ int main(void) {
This is how the example in "Using the Parsed JSON" could be written using only error code checking:
```c++
auto cars_json = R"( [
std::string cars_json = R"( [
{ "make": "Toyota", "model": "Camry", "year": 2018, "tire_pressure": [ 40.1, 39.9, 37.7, 40.4 ] },
{ "make": "Kia", "model": "Soul", "year": 2012, "tire_pressure": [ 30.1, 31.0, 28.6, 28.7 ] },
{ "make": "Toyota", "model": "Tercel", "year": 1999, "tire_pressure": [ 29.8, 30.0, 30.2, 30.5 ] }
] )"_padded;
] )";
dom::parser parser;
dom::array cars;
auto error = parser.parse(cars_json).get(cars);
@@ -813,10 +810,10 @@ for (dom::element car_element : cars) {
Here is another example:
```C++
auto abstract_json = R"( [
std::string abstract_json = R"( [
{ "12345" : {"a":12.34, "b":56.78, "c": 9998877} },
{ "12545" : {"a":11.44, "b":12.78, "c": 11111111} }
] )"_padded;
] )";
dom::parser parser;
dom::array array;
auto error = parser.parse(abstract_json).get(array);
@@ -846,8 +843,8 @@ for (dom::element elem : array) {
And another one:
```C++
auto abstract_json = R"(
{ "str" : { "123" : {"abc" : 3.14 } } } )"_padded;
std::string abstract_json = R"(
{ "str" : { "123" : {"abc" : 3.14 } } } )";
dom::parser parser;
double v;
auto error = parser.parse(abstract_json)["str"]["123"]["abc"].get(v);
@@ -926,11 +923,11 @@ before printout the data.
```C++
ondemand::parser parser;
auto cars_json = R"( [
std::string cars_json = R"( [
{ "make": "Toyota", "model": "Camry", "year": 2018, "tire_pressure": [ 40.1, 39.9, 37.7, 40.4 ] },
{ "make": "Kia", "model": "Soul", "year": 2012, "tire_pressure": [ 30.1, 31.0, 28.6, 28.7 ] },
{ "make": "Toyota", "model": "Tercel", "year": 1999, "tire_pressure": [ 29.8, 30.0, 30.2, 30.5 ] }
] )"_padded;
] )";
auto doc = parser.iterate(cars_json);
for (simdjson_unused ondemand::object car : doc) {
@@ -957,7 +954,7 @@ parse as you see fit.
```C++
simdjson::ondemand::parser parser;
simdjson::padded_string docdata = R"({"value":12321323213213213213213213213211223})"_padded;
std::string docdata = R"({"value":12321323213213213213213213213211223})";
simdjson::ondemand::document doc = parser.iterate(docdata);
simdjson::ondemand::object obj = doc.get_object();
std::string_view token = obj["value"].raw_json_token();
@@ -970,7 +967,7 @@ source document.
```C++
simdjson::ondemand::parser parser;
simdjson::padded_string docdata = R"({"value":"12321323213213213213213213213211223"})"_padded;
std::string docdata = R"({"value":"12321323213213213213213213213211223"})";
simdjson::ondemand::document doc = parser.iterate(docdata);
simdjson::ondemand::object obj = doc.get_object();
string_view token = obj["value"].raw_json_token();
@@ -993,7 +990,7 @@ than 4GB), though each individual document must be no larger than 4 GB.
Here is a simple example:
```c++
auto json = R"({ "foo": 1 } { "foo": 2 } { "foo": 3 } )"_padded;
std::string json = R"({ "foo": 1 } { "foo": 2 } { "foo": 3 } )";
ondemand::parser parser;
ondemand::document_stream docs = parser.iterate_many(json);
for (auto & doc : docs) {
@@ -1007,7 +1004,7 @@ It is important to note that the iteration returns a `document` reference, and h
Unlike `parser.iterate`, `parser.iterate_many` may parse "on demand" (lazily). That is, no parsing may have been done before you enter the loop
`for (auto & doc : docs) {` and you should expect the parser to only ever fully parse one JSON document at a time.
As with `parser.iterate`, when calling `parser.iterate_many(string)`, no copy is made of the provided string input. The provided memory buffer may be accessed each time a JSON document is parsed. Calling `parser.iterate_many(string)` on a temporary string buffer (e.g., `docs = parser.parse_many("[1,2,3]"_padded)`) is unsafe (and will not compile) because the `document_stream` instance needs access to the buffer to return the JSON documents.
As with `parser.iterate`, when calling `parser.iterate_many(string)`, no copy is made of the provided string input. The provided memory buffer may be accessed each time a JSON document is parsed. Calling `parser.iterate_many(string)` on a temporary string buffer (e.g., `docs = parser.parse_many("[1,2,3]")`) is unsafe (and will not compile) because the `document_stream` instance needs access to the buffer to return the JSON documents.
`iterate_many` can also take an optional parameter `size_t batch_size` which defines the window processing size. It is set by default to a large value (`1000000` corresponding to 1 MB). None of your JSON documents should exceed this window size, or else you will get the error `simdjson::CAPACITY`. You cannot set this window size larger than 4 GB: you will get the error `simdjson::CAPACITY`. The smaller the window size is, the less memory the function will use. Setting the window size too small (e.g., less than 100 kB) may also impact performance negatively. Leaving it to 1 MB is expected to be a good choice, unless you have some larger documents.
@@ -345,7 +345,7 @@ simdjson_really_inline std::string_view document_stream::iterator::source() cons
cur_struct_index++;
}
return std::string_view(reinterpret_cast<const char*>(stream->buf) + current_index(), stream->parser->implementation->structural_indexes[cur_struct_index] - current_index() + stream->batch_start + 1);;
return std::string_view(reinterpret_cast<const char*>(stream->buf) + current_index(), stream->parser->implementation->structural_indexes[cur_struct_index] - current_index() + stream->batch_start + 1);
}
inline error_code document_stream::iterator::error() const noexcept {
@@ -109,6 +109,9 @@ public:
simdjson_warn_unused simdjson_result<document> iterate(const simdjson_result<padded_string_view> &json) & noexcept;
/** @overload simdjson_result<document> iterate(padded_string_view json) & noexcept */
simdjson_warn_unused simdjson_result<document> iterate(padded_string &&json) & noexcept = delete;
/** @overload simdjson_result<document> iterate(padded_string_view json) & noexcept */
simdjson_warn_unused simdjson_result<document> iterate(std::string &&json) & noexcept = delete;
/**
* @private
+1
View File
@@ -110,6 +110,7 @@ inline const char *padded_string::data() const noexcept { return data_ptr; }
inline char *padded_string::data() noexcept { return data_ptr; }
inline padded_string::operator std::string_view() const { return std::string_view(data(), length()); }
inline std::string padded_string::to_string() const { return std::string(data(), length()); }
inline padded_string::operator padded_string_view() const noexcept {
return padded_string_view(data(), length(), length() + SIMDJSON_PADDING);
+5
View File
@@ -98,6 +98,11 @@ struct padded_string final {
*/
operator std::string_view() const;
/**
* Create a std::string with the same content (and no padding).
*/
std::string to_string() const;
/**
* Create a padded_string_view with the same content.
*/
+4 -4
View File
@@ -86,7 +86,7 @@ namespace document_stream_tests {
bool stress_data_race() {
std::cout << "Running " << __func__ << std::endl;
// Correct JSON.
const simdjson::padded_string input = R"([1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] )"_padded;;
const simdjson::padded_string input = R"([1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] )"_padded;
simdjson::dom::parser parser;
simdjson::dom::document_stream stream;
ASSERT_SUCCESS(parser.parse_many(input, 32).get(stream));
@@ -103,7 +103,7 @@ namespace document_stream_tests {
bool stress_data_race_with_error() {
std::cout << "Running " << __func__ << std::endl;
// Intentionally broken
const simdjson::padded_string input = R"([1,23] [1,23] [1,23] [1,23 [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] )"_padded;;
const simdjson::padded_string input = R"([1,23] [1,23] [1,23] [1,23 [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] )"_padded;
simdjson::dom::parser parser;
simdjson::dom::document_stream stream;
ASSERT_SUCCESS(parser.parse_many(input, 32).get(stream));
@@ -129,7 +129,7 @@ namespace document_stream_tests {
bool test_leading_spaces() {
std::cout << "Running " << __func__ << std::endl;
const simdjson::padded_string input = R"( [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] )"_padded;;
const simdjson::padded_string input = R"( [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] )"_padded;
size_t count = 0;
simdjson::dom::parser parser;
simdjson::dom::document_stream stream;
@@ -149,7 +149,7 @@ namespace document_stream_tests {
bool test_crazy_leading_spaces() {
std::cout << "Running " << __func__ << std::endl;
const simdjson::padded_string input = R"( [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] )"_padded;;
const simdjson::padded_string input = R"( [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] )"_padded;
size_t count = 0;
simdjson::dom::parser parser;
simdjson::dom::document_stream stream;
+1 -1
View File
@@ -182,7 +182,7 @@ bool issue1142() {
const char * input_array = "[]";
size_t input_length = std::strlen(input_array);
auto element4 = parser.parse(input_array, input_length).at_pointer("");;
auto element4 = parser.parse(input_array, input_length).at_pointer("");
ASSERT_EQUAL(std::string(R"([])"), simdjson::minify(element4));
#endif
@@ -6,10 +6,9 @@ using namespace simdjson;
int main() {
ondemand::parser parser;
#if COMPILATION_TEST_USE_FAILING_CODE
const char* json;
auto doc = parser.iterate(json, strlen(json));
auto doc = parser.iterate("1");
#else
auto json = "1"_padded;
std::string json = "1";
auto doc = parser.iterate(json);
#endif
int64_t value;
@@ -6,9 +6,9 @@ using namespace simdjson;
int main() {
ondemand::parser parser;
#if COMPILATION_TEST_USE_FAILING_CODE
auto doc = parser.iterate("1"_padded);
auto doc = parser.iterate(std::string("1"));
#else
auto json = "1"_padded;
std::string json = "1";
auto doc = parser.iterate(json);
#endif
int64_t value;
@@ -15,7 +15,7 @@ int main() {
auto json = std::string_view("1");
auto doc = parser.iterate(json);
#else
auto json = "1"_padded;
std::string json = "1";
auto doc = parser.iterate(json);
#endif
int64_t value;
+3 -3
View File
@@ -10,7 +10,7 @@ namespace active_tests {
bool parser_child() {
TEST_START();
ondemand::parser parser;
const padded_string json = R"({ "parent": {"child1": {"name": "John"} , "child2": {"name": "Daniel"}} })"_padded;
const std::string json = R"({ "parent": {"child1": {"name": "John"} , "child2": {"name": "Daniel"}} })";
auto doc = parser.iterate(json);
ondemand::object parent = doc["parent"];
{
@@ -27,7 +27,7 @@ namespace active_tests {
bool parser_doc_correct() {
TEST_START();
ondemand::parser parser;
const padded_string json = R"({ "key1": 1, "key2":2, "key3": 3 })"_padded;
const std::string json = R"({ "key1": 1, "key2":2, "key3": 3 })";
auto doc = parser.iterate(json);
ondemand::object root_object = doc.get_object();
int64_t k1 = root_object["key1"];
@@ -39,7 +39,7 @@ namespace active_tests {
bool parser_doc_limits() {
TEST_START();
ondemand::parser parser;
const padded_string json = R"({ "key1": 1, "key2":2, "key3": 3 })"_padded;
const std::string json = R"({ "key1": 1, "key2":2, "key3": 3 })";
auto doc = parser.iterate(json);
int64_t k1 = doc["key1"];
try {
@@ -116,7 +116,7 @@ namespace array_error_tests {
#ifdef SIMDJSON_DEVELOPMENT_CHECKS
bool out_of_order_array_iteration_error() {
TEST_START();
auto json = R"([ [ 1, 2 ] ])"_padded;
std::string json = R"([ [ 1, 2 ] ])";
SUBTEST("simdjson_result<value>", test_ondemand_doc(json, [&](auto doc) {
for (auto arr : doc) {
for (auto subelement : arr) { ASSERT_SUCCESS(subelement); }
@@ -155,7 +155,7 @@ namespace array_error_tests {
bool out_of_order_top_level_array_iteration_error() {
TEST_START();
auto json = R"([ 1, 2 ])"_padded;
std::string json = R"([ 1, 2 ])";
SUBTEST("simdjson_result<document>", test_ondemand_doc(json, [&](auto arr) {
for (auto element : arr) { ASSERT_SUCCESS(element); }
ASSERT_ITERATE_ERROR( arr, OUT_OF_ORDER_ITERATION );
@@ -18,11 +18,11 @@ simdjson_never_inline bool check_point(simdjson_result<ondemand::value> xval, si
}
bool test_check_point() {
auto json = R"(
std::string json = R"(
{
"x": 1,
"y": 2 3
)"_padded;
)";
ondemand::parser parser;
auto doc = parser.iterate(json);
return check_point(doc["x"], doc["y"]);
@@ -13,7 +13,7 @@ void process3(int ) {}
// Do not run this, it is only meant to compile
void compilation_test_1() {
const padded_string bogus = ""_padded;
const std::string bogus = "";
ondemand::parser parser;
auto doc = parser.iterate(bogus);
for (ondemand::object my_object : doc["mykey"]) {
@@ -27,7 +27,7 @@ void compilation_test_1() {
// Do not run this, it is only meant to compile
void compilation_test_2() {
const padded_string bogus = ""_padded;
const std::string bogus = "";
ondemand::parser parser;
auto doc = parser.iterate(bogus);
std::set<std::string_view> default_users;
@@ -44,7 +44,7 @@ void compilation_test_1() {
// Do not run this, it is only meant to compile
void compilation_test_3() {
const padded_string bogus = ""_padded;
const std::string bogus = "";
ondemand::parser parser;
auto doc = parser.iterate(bogus);
ondemand::array tweets;
@@ -13,7 +13,7 @@ namespace document_stream_tests {
bool simple_document_iteration() {
TEST_START();
auto json = R"([1,[1,2]] {"a":1,"b":2} {"o":{"1":1,"2":2}} [1,2,3])"_padded;
std::string json = R"([1,[1,2]] {"a":1,"b":2} {"o":{"1":1,"2":2}} [1,2,3])";
ondemand::parser parser;
ondemand::document_stream stream;
ASSERT_SUCCESS(parser.iterate_many(json).get(stream));
@@ -29,7 +29,7 @@ namespace document_stream_tests {
bool simple_document_iteration_multiple_batches() {
TEST_START();
auto json = R"([1,[1,2]] {"a":1,"b":2} {"o":{"1":1,"2":2}} [1,2,3])"_padded;
std::string json = R"([1,[1,2]] {"a":1,"b":2} {"o":{"1":1,"2":2}} [1,2,3])";
ondemand::parser parser;
ondemand::document_stream stream;
ASSERT_SUCCESS(parser.iterate_many(json,32).get(stream));
@@ -45,7 +45,7 @@ namespace document_stream_tests {
bool simple_document_iteration_with_parsing() {
TEST_START();
auto json = R"([1,[1,2]] {"a":1,"b":2} {"o":{"1":1,"2":2}} [1,2,3])"_padded;
std::string json = R"([1,[1,2]] {"a":1,"b":2} {"o":{"1":1,"2":2}} [1,2,3])";
ondemand::parser parser;
ondemand::document_stream stream;
ASSERT_SUCCESS(parser.iterate_many(json).get(stream));
@@ -81,7 +81,7 @@ namespace document_stream_tests {
bool atoms_json() {
TEST_START();
auto json = R"(5 true 20.3 "string" )"_padded;
std::string json = R"(5 true 20.3 "string" )";
ondemand::parser parser;
ondemand::document_stream stream;
ASSERT_SUCCESS(parser.iterate_many(json).get(stream));
@@ -97,7 +97,7 @@ namespace document_stream_tests {
bool doc_index() {
TEST_START();
auto json = R"({"z":5} {"1":1,"2":2,"4":4} [7, 10, 9] [15, 11, 12, 13] [154, 110, 112, 1311])"_padded;
std::string json = R"({"z":5} {"1":1,"2":2,"4":4} [7, 10, 9] [15, 11, 12, 13] [154, 110, 112, 1311])";
std::string_view expected[5] = {R"({"z":5})",R"({"1":1,"2":2,"4":4})","[7, 10, 9]","[15, 11, 12, 13]","[154, 110, 112, 1311]"};
size_t expected_indexes[5] = {0, 9, 29, 44, 65};
@@ -117,7 +117,7 @@ namespace document_stream_tests {
bool doc_index_multiple_batches() {
TEST_START();
auto json = R"({"z":5} {"1":1,"2":2,"4":4} [7, 10, 9] [15, 11, 12, 13] [154, 110, 112, 1311])"_padded;
std::string json = R"({"z":5} {"1":1,"2":2,"4":4} [7, 10, 9] [15, 11, 12, 13] [154, 110, 112, 1311])";
std::string_view expected[5] = {R"({"z":5})",R"({"1":1,"2":2,"4":4})","[7, 10, 9]","[15, 11, 12, 13]","[154, 110, 112, 1311]"};
size_t expected_indexes[5] = {0, 9, 29, 44, 65};
@@ -137,7 +137,7 @@ namespace document_stream_tests {
bool source_test() {
TEST_START();
auto json = R"([1,[1,2]] {"a":1,"b":2} {"o":{"1":1,"2":2}} [1,2,3] )"_padded;
std::string json = R"([1,[1,2]] {"a":1,"b":2} {"o":{"1":1,"2":2}} [1,2,3] )";
ondemand::parser parser;
ondemand::document_stream stream;
ASSERT_SUCCESS(parser.iterate_many(json).get(stream));
@@ -153,7 +153,7 @@ namespace document_stream_tests {
bool truncated() {
TEST_START();
// The last JSON document is intentionally truncated.
auto json = R"([1,2,3] {"1":1,"2":3,"4":4} [1,2 )"_padded;
std::string json = R"([1,2,3] {"1":1,"2":3,"4":4} [1,2 )";
ondemand::parser parser;
ondemand::document_stream stream;
ASSERT_SUCCESS(parser.iterate_many(json).get(stream));
@@ -170,7 +170,7 @@ namespace document_stream_tests {
bool truncated_complete_docs() {
TEST_START();
auto json = R"([1,2,3] {"1":1,"2":3,"4":4} [1,2] )"_padded;
std::string json = R"([1,2,3] {"1":1,"2":3,"4":4} [1,2] )";
ondemand::parser parser;
ondemand::document_stream stream;
ASSERT_SUCCESS(parser.iterate_many(json).get(stream));
@@ -188,7 +188,7 @@ namespace document_stream_tests {
bool truncated_unclosed_string() {
TEST_START();
// The last JSON document is intentionally truncated.
auto json = R"([1,2,3] {"1":1,"2":3,"4":4} "intentionally unclosed string )"_padded;
std::string json = R"([1,2,3] {"1":1,"2":3,"4":4} "intentionally unclosed string )";
ondemand::parser parser;
ondemand::document_stream stream;
// We use a window of json.size() though any large value would do.
@@ -205,7 +205,7 @@ namespace document_stream_tests {
bool truncated_unclosed_string_in_object() {
// The last JSON document is intentionally truncated.
auto json = R"([1,2,3] {"1":1,"2":3,"4":4} {"key":"intentionally unclosed string )"_padded;
std::string json = R"([1,2,3] {"1":1,"2":3,"4":4} {"key":"intentionally unclosed string )";
ondemand::parser parser;
ondemand::document_stream stream;
ASSERT_SUCCESS( parser.iterate_many(json).get(stream) );
@@ -240,7 +240,7 @@ namespace document_stream_tests {
bool large_window() {
TEST_START();
#if SIZE_MAX > 17179869184
auto json = R"({"error":[],"result":{"token":"xxx"}}{"error":[],"result":{"token":"xxx"}})"_padded;
std::string json = R"({"error":[],"result":{"token":"xxx"}}{"error":[],"result":{"token":"xxx"}})";
ondemand::parser parser;
uint64_t window_size{17179869184}; // deliberately too big
ondemand::document_stream stream;
@@ -253,7 +253,7 @@ namespace document_stream_tests {
bool test_leading_spaces() {
TEST_START();
auto input = R"( [1,1] [1,2] [1,3] [1,4] [1,5] [1,6] [1,7] [1,8] [1,9] [1,10] [1,11] [1,12] [1,13] [1,14] [1,15] )"_padded;;
std::string input = R"( [1,1] [1,2] [1,3] [1,4] [1,5] [1,6] [1,7] [1,8] [1,9] [1,10] [1,11] [1,12] [1,13] [1,14] [1,15] )";
size_t count{0};
ondemand::parser parser;
ondemand::document_stream stream;
@@ -269,7 +269,7 @@ namespace document_stream_tests {
bool test_crazy_leading_spaces() {
TEST_START();
auto input = R"( [1,1] [1,2] [1,3] [1,4] [1,5] [1,6] [1,7] [1,8] [1,9] [1,10] [1,11] [1,12] [1,13] [1,14] [1,15] )"_padded;;
std::string input = R"( [1,1] [1,2] [1,3] [1,4] [1,5] [1,6] [1,7] [1,8] [1,9] [1,10] [1,11] [1,12] [1,13] [1,14] [1,15] )";
size_t count{0};
ondemand::parser parser;
ondemand::document_stream stream;
@@ -284,7 +284,7 @@ namespace document_stream_tests {
bool adversarial_single_document() {
TEST_START();
auto json = R"({"f[)"_padded;
std::string json = R"({"f[)";
ondemand::parser parser;
ondemand::document_stream stream;
ASSERT_SUCCESS(parser.iterate_many(json).get(stream));
@@ -299,7 +299,7 @@ namespace document_stream_tests {
bool adversarial_single_document_array() {
TEST_START();
auto json = R"(["this is an unclosed string ])"_padded;
std::string json = R"(["this is an unclosed string ])";
ondemand::parser parser;
ondemand::document_stream stream;
ASSERT_SUCCESS(parser.iterate_many(json).get(stream));
@@ -388,7 +388,7 @@ namespace document_stream_tests {
bool stress_data_race() {
TEST_START();
// Correct JSON.
auto input = R"([1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] )"_padded;;
std::string input = R"([1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] )";
ondemand::parser parser;
ondemand::document_stream stream;
ASSERT_SUCCESS(parser.iterate_many(input, 32).get(stream));
@@ -404,7 +404,7 @@ namespace document_stream_tests {
std::cout << "ENABLED" << std::endl;
#endif
// Intentionally broken
auto input = R"([1,23] [1,23] [1,23] [1,23 [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] )"_padded;
std::string input = R"([1,23] [1,23] [1,23] [1,23 [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] [1,23] )";
ondemand::parser parser;
ondemand::document_stream stream;
ASSERT_SUCCESS(parser.iterate_many(input, 32).get(stream));
+5 -5
View File
@@ -9,7 +9,7 @@ namespace error_tests {
bool empty_document_error() {
TEST_START();
ondemand::parser parser;
auto json = ""_padded;
std::string json = "";
ASSERT_ERROR( parser.iterate(json), EMPTY );
TEST_SUCCEED();
}
@@ -26,7 +26,7 @@ namespace error_tests {
bool get_fail_then_succeed_bool() {
TEST_START();
auto json = R"({ "val" : true })"_padded;
std::string json = R"({ "val" : true })";
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
@@ -66,7 +66,7 @@ namespace error_tests {
ASSERT_SUCCESS( val.get_bool() );
TEST_SUCCEED();
}));
json = R"(true)"_padded;
json = R"(true)";
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 );
@@ -110,7 +110,7 @@ namespace error_tests {
bool get_fail_then_succeed_null() {
TEST_START();
auto json = R"({ "val" : null })"_padded;
std::string json = R"({ "val" : null })";
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
@@ -150,7 +150,7 @@ namespace error_tests {
ASSERT_EQUAL( val.is_null(), true );
TEST_SUCCEED();
}));
json = R"(null)"_padded;
json = R"(null)";
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_ERROR( val.get_bool(), INCORRECT_TYPE );
+21 -21
View File
@@ -5,7 +5,7 @@
using namespace simdjson;
namespace json_pointer_tests {
const padded_string TEST_JSON = R"(
const std::string TEST_JSON = R"(
{
"/~01abc": [
0,
@@ -21,9 +21,9 @@ namespace json_pointer_tests {
"": "empty ok",
"arr": []
}
)"_padded;
)";
const padded_string TEST_RFC_JSON = R"(
const std::string TEST_RFC_JSON = R"(
{
"foo": ["bar", "baz"],
"": 0,
@@ -36,7 +36,7 @@ namespace json_pointer_tests {
" ": 7,
"m~n": 8
}
)"_padded;
)";
bool run_success_test(const padded_string & json,std::string_view json_pointer,std::string expected) {
TEST_START();
@@ -63,11 +63,11 @@ namespace json_pointer_tests {
bool demo_test() {
TEST_START();
auto cars_json = R"( [
std::string cars_json = R"( [
{ "make": "Toyota", "model": "Camry", "year": 2018, "tire_pressure": [ 40.1, 39.9, 37.7, 40.4 ] },
{ "make": "Kia", "model": "Soul", "year": 2012, "tire_pressure": [ 30.1, 31.0, 28.6, 28.7 ] },
{ "make": "Toyota", "model": "Tercel", "year": 1999, "tire_pressure": [ 29.8, 30.0, 30.2, 30.5 ] }
] )"_padded;
] )";
ondemand::parser parser;
ondemand::document cars;
@@ -80,11 +80,11 @@ namespace json_pointer_tests {
bool demo_relative_path() {
TEST_START();
auto cars_json = R"( [
std::string cars_json = R"( [
{ "make": "Toyota", "model": "Camry", "year": 2018, "tire_pressure": [ 40.1, 39.9, 37.7, 40.4 ] },
{ "make": "Kia", "model": "Soul", "year": 2012, "tire_pressure": [ 30.1, 31.0, 28.6, 28.7 ] },
{ "make": "Toyota", "model": "Tercel", "year": 1999, "tire_pressure": [ 29.8, 30.0, 30.2, 30.5 ] }
] )"_padded;
] )";
ondemand::parser parser;
ondemand::document cars;
@@ -103,11 +103,11 @@ namespace json_pointer_tests {
bool many_json_pointers() {
TEST_START();
auto cars_json = R"( [
std::string cars_json = R"( [
{ "make": "Toyota", "model": "Camry", "year": 2018, "tire_pressure": [ 40.1, 39.9, 37.7, 40.4 ] },
{ "make": "Kia", "model": "Soul", "year": 2012, "tire_pressure": [ 30.1, 31.0, 28.6, 28.7 ] },
{ "make": "Toyota", "model": "Tercel", "year": 1999, "tire_pressure": [ 29.8, 30.0, 30.2, 30.5 ] }
] )"_padded;
] )";
ondemand::parser parser;
ondemand::document cars;
@@ -131,12 +131,12 @@ namespace json_pointer_tests {
ondemand::value v;
std::string_view val;
auto invalid_escape_key = R"( {"hello": [0,1,2,3], "te\est": "foo", "bool": true, "num":1234, "success":"yes"} )"_padded;
auto invalid_escape_value = R"( {"hello": [0,1,2,3], "test": "fo\eo", "bool": true, "num":1234, "success":"yes"} )"_padded;
auto invalid_escape_value_at_jp = R"( {"hello": [0,1,2,3], "test": "foo", "bool": true, "num":1234, "success":"y\es"} )"_padded;
auto unclosed_object = R"( {"test": "foo", "bool": true, "num":1234, "success":"yes" )"_padded;
auto missing_bracket_before = R"( {"hello": [0,1,2,3, "test": "foo", "bool": true, "num":1234, "success":"yes"} )"_padded;
auto missing_bracket_after = R"( {"test": "foo", "bool": true, "num":1234, "success":"yes", "hello":[0,1,2,3} )"_padded;
std::string invalid_escape_key = R"( {"hello": [0,1,2,3], "te\est": "foo", "bool": true, "num":1234, "success":"yes"} )";
std::string invalid_escape_value = R"( {"hello": [0,1,2,3], "test": "fo\eo", "bool": true, "num":1234, "success":"yes"} )";
std::string invalid_escape_value_at_jp = R"( {"hello": [0,1,2,3], "test": "foo", "bool": true, "num":1234, "success":"y\es"} )";
std::string unclosed_object = R"( {"test": "foo", "bool": true, "num":1234, "success":"yes" )";
std::string missing_bracket_before = R"( {"hello": [0,1,2,3, "test": "foo", "bool": true, "num":1234, "success":"yes"} )";
std::string missing_bracket_after = R"( {"test": "foo", "bool": true, "num":1234, "success":"yes", "hello":[0,1,2,3} )";
std::string json_pointer = "/success";
std::cout << "\t- invalid_escape_key" << std::endl;
@@ -166,7 +166,7 @@ namespace json_pointer_tests {
bool many_json_pointers_object_array() {
TEST_START();
auto dogcatpotato = R"( { "dog" : [1,2,3], "cat" : [5, 6, 7], "potato" : [1234]})"_padded;
std::string dogcatpotato = R"( { "dog" : [1,2,3], "cat" : [5, 6, 7], "potato" : [1234]})";
ondemand::parser parser;
ondemand::document doc;
@@ -182,7 +182,7 @@ namespace json_pointer_tests {
}
bool many_json_pointers_object() {
TEST_START();
auto cfoofoo2 = R"( { "c" :{ "foo": { "a": [ 10, 20, 30 ] }}, "d": { "foo2": { "a": [ 10, 20, 30 ] }} , "e": 120 })"_padded;
std::string cfoofoo2 = R"( { "c" :{ "foo": { "a": [ 10, 20, 30 ] }}, "d": { "foo2": { "a": [ 10, 20, 30 ] }} , "e": 120 })";
ondemand::parser parser;
ondemand::document doc;
ASSERT_SUCCESS(parser.iterate(cfoofoo2).get(doc));
@@ -199,7 +199,7 @@ namespace json_pointer_tests {
}
bool many_json_pointers_array() {
TEST_START();
auto cfoofoo2 = R"( [ 111, 2, 3, { "foo": { "a": [ 10, 20, 33 ] }}, { "foo2": { "a": [ 10, 20, 30 ] }}, 1001 ])"_padded;
std::string cfoofoo2 = R"( [ 111, 2, 3, { "foo": { "a": [ 10, 20, 33 ] }}, { "foo2": { "a": [ 10, 20, 30 ] }}, 1001 ])";
ondemand::parser parser;
ondemand::document doc;
ASSERT_SUCCESS(parser.iterate(cfoofoo2).get(doc));
@@ -222,11 +222,11 @@ namespace json_pointer_tests {
bool json_pointer_invalidation() {
TEST_START();
auto cars_json = R"( [
std::string cars_json = R"( [
{ "make": "Toyota", "model": "Camry", "year": 2018, "tire_pressure": [ 40.1, 39.9, 37.7, 40.4 ] },
{ "make": "Kia", "model": "Soul", "year": 2012, "tire_pressure": [ 30.1, 31.0, 28.6, 28.7 ] },
{ "make": "Toyota", "model": "Tercel", "year": 1999, "tire_pressure": [ 29.8, 30.0, 30.2, 30.5 ] }
] )"_padded;
] )";
ondemand::parser parser;
ondemand::document cars;
+1 -1
View File
@@ -8,7 +8,7 @@ namespace key_string_tests {
bool parser_key_value() {
TEST_START();
ondemand::parser parser;
const padded_string json = R"({ "1": "1", "2": "2", "3": "3", "abc": "abc", "\u0075": "\u0075" })"_padded;
const std::string json = R"({ "1": "1", "2": "2", "3": "3", "abc": "abc", "\u0075": "\u0075" })";
auto doc = parser.iterate(json);
for(auto field : doc.get_object()) {
std::string_view keyv = field.unescaped_key();
+17 -18
View File
@@ -9,7 +9,7 @@ namespace misc_tests {
bool issue1661a() {
TEST_START();
ondemand::parser parser;
padded_string docdata = R"({"":],"global-groups":[[]}})"_padded;
std::string docdata = R"({"":],"global-groups":[[]}})";
ondemand::document doc;
ASSERT_SUCCESS(parser.iterate(docdata).get(doc));
ondemand::value global_groups;
@@ -23,7 +23,7 @@ namespace misc_tests {
bool issue1660() {
TEST_START();
ondemand::parser parser;
padded_string docdata = R"({"globals":{"a":{"shadowable":[}}}})"_padded;
std::string docdata = R"({"globals":{"a":{"shadowable":[}}}})";
ondemand::document doc;
ASSERT_SUCCESS(parser.iterate(docdata).get(doc));
ondemand::object globals;
@@ -54,7 +54,7 @@ namespace misc_tests {
bool issue1660_with_bool() {
TEST_START();
ondemand::parser parser;
padded_string docdata = R"({"globals":{"a":{"shadowable":[}}}})"_padded;
std::string docdata = R"({"globals":{"a":{"shadowable":[}}}})";
ondemand::document doc;
ASSERT_SUCCESS(parser.iterate(docdata).get(doc));
ondemand::object globals;
@@ -85,7 +85,7 @@ namespace misc_tests {
bool issue1660_with_uint64() {
TEST_START();
ondemand::parser parser;
padded_string docdata = R"({"globals":{"a":{"shadowable":[}}}})"_padded;
std::string docdata = R"({"globals":{"a":{"shadowable":[}}}})";
ondemand::document doc;
ASSERT_SUCCESS(parser.iterate(docdata).get(doc));
ondemand::object globals;
@@ -116,7 +116,7 @@ namespace misc_tests {
bool issue1660_with_int64() {
TEST_START();
ondemand::parser parser;
padded_string docdata = R"({"globals":{"a":{"shadowable":[}}}})"_padded;
std::string docdata = R"({"globals":{"a":{"shadowable":[}}}})";
ondemand::document doc;
ASSERT_SUCCESS(parser.iterate(docdata).get(doc));
ondemand::object globals;
@@ -146,7 +146,7 @@ namespace misc_tests {
bool issue1660_with_double() {
TEST_START();
ondemand::parser parser;
padded_string docdata = R"({"globals":{"a":{"shadowable":[}}}})"_padded;
std::string docdata = R"({"globals":{"a":{"shadowable":[}}}})";
ondemand::document doc;
ASSERT_SUCCESS(parser.iterate(docdata).get(doc));
ondemand::object globals;
@@ -177,7 +177,7 @@ namespace misc_tests {
bool issue1660_with_null() {
TEST_START();
ondemand::parser parser;
padded_string docdata = R"({"globals":{"a":{"shadowable":[}}}})"_padded;
std::string docdata = R"({"globals":{"a":{"shadowable":[}}}})";
ondemand::document doc;
ASSERT_SUCCESS(parser.iterate(docdata).get(doc));
ondemand::object globals;
@@ -208,7 +208,7 @@ namespace misc_tests {
bool issue1660_with_string() {
TEST_START();
ondemand::parser parser;
padded_string docdata = R"({"globals":{"a":{"shadowable":[}}}})"_padded;
std::string docdata = R"({"globals":{"a":{"shadowable":[}}}})";
ondemand::document doc;
ASSERT_SUCCESS(parser.iterate(docdata).get(doc));
ondemand::object globals;
@@ -238,7 +238,7 @@ namespace misc_tests {
bool issue1661() {
TEST_START();
ondemand::parser parser;
padded_string docdata = R"({"":],"global-groups":[[]}})"_padded;
std::string docdata = R"({"":],"global-groups":[[]}})";
ondemand::document doc;
ASSERT_SUCCESS(parser.iterate(docdata).get(doc));
ondemand::object global_groups;
@@ -252,7 +252,7 @@ namespace misc_tests {
simdjson_warn_unused bool big_integer() {
TEST_START();
simdjson::ondemand::parser parser;
simdjson::padded_string docdata = R"({"value":12321323213213213213213213213211223})"_padded;
std::string docdata = R"({"value":12321323213213213213213213213211223})";
simdjson::ondemand::document doc;
ASSERT_SUCCESS(parser.iterate(docdata).get(doc));
simdjson::ondemand::object o;
@@ -265,7 +265,7 @@ namespace misc_tests {
simdjson_warn_unused bool big_integer_in_string() {
TEST_START();
simdjson::ondemand::parser parser;
simdjson::padded_string docdata = R"({"value":"12321323213213213213213213213211223"})"_padded;
std::string docdata = R"({"value":"12321323213213213213213213213211223"})";
simdjson::ondemand::document doc;
ASSERT_SUCCESS(parser.iterate(docdata).get(doc));
simdjson::ondemand::object o;
@@ -275,17 +275,16 @@ namespace misc_tests {
ASSERT_EQUAL(token, "\"12321323213213213213213213213211223\"");
return true;
}
simdjson_warn_unused bool test_raw_json_token(string_view json, string_view expected_token, int expected_start_index = 0) {
simdjson_warn_unused bool test_raw_json_token(string json, string_view expected_token, int expected_start_index = 0) {
string title = "'";
title.append(json.data(), json.length());
title += "'";
padded_string json_padded = json;
SUBTEST(title, test_ondemand_doc(json_padded, [&](auto doc) {
SUBTEST(title, test_ondemand_doc(json, [&](auto doc) {
string_view token;
ASSERT_SUCCESS( doc.raw_json_token().get(token) );
ASSERT_EQUAL( token, expected_token );
// Validate the text is inside the original buffer
ASSERT_EQUAL( reinterpret_cast<const void*>(token.data()), reinterpret_cast<const void*>(&json_padded.data()[expected_start_index]));
ASSERT_EQUAL( reinterpret_cast<const void*>(token.data()), reinterpret_cast<const void*>(&json.data()[expected_start_index]));
return true;
}));
@@ -293,22 +292,22 @@ namespace misc_tests {
auto json_in_hash = string(R"({"a":)");
json_in_hash.append(json.data(), json.length());
json_in_hash += "}";
json_padded = json_in_hash;
title = "'";
title.append(json_in_hash.data(), json_in_hash.length());
title += "'";
SUBTEST(title, test_ondemand_doc(json_padded, [&](auto doc) {
SUBTEST(title, test_ondemand_doc(json_in_hash, [&](auto doc) {
string_view token;
ASSERT_SUCCESS( doc["a"].raw_json_token().get(token) );
ASSERT_EQUAL( token, expected_token );
// Validate the text is inside the original buffer
// Adjust for the {"a":
ASSERT_EQUAL( reinterpret_cast<const void*>(token.data()), reinterpret_cast<const void*>(&json_padded.data()[5+expected_start_index]));
ASSERT_EQUAL( reinterpret_cast<const void*>(token.data()), reinterpret_cast<const void*>(&json_in_hash.data()[5+expected_start_index]));
return true;
}));
return true;
}
//bool raw_json_token() { return true; }
bool raw_json_token() {
TEST_START();
+4 -4
View File
@@ -26,7 +26,7 @@ namespace number_tests {
std::cout << __func__ << std::endl;
// converts the double "expected" to a padded string
auto format_into_padded=[](const double expected) -> padded_string
auto format_into_padded=[](const double expected) -> std::string
{
std::vector<char> buf(1024);
const auto n = std::snprintf(buf.data(),
@@ -36,7 +36,7 @@ namespace number_tests {
expected);
const auto nz=static_cast<size_t>(n);
if (n<0 || nz >= buf.size()) { std::abort(); }
return padded_string(buf.data(), nz);
return std::string(buf.data(), nz);
};
for (int i = -1075; i < 1024; ++i) {// large negative values should be zero.
@@ -146,8 +146,8 @@ namespace number_tests {
if (n >= buf.size()) { std::abort(); }
std::fflush(nullptr);
const double expected = ((i >= -307) ? testing_power_of_ten[i + 307]: std::pow(10, i));
if(!test_ondemand<double>(padded_string(buf.data(), n), [&](double actual) {
std::string str(buf.data(), n);
if(!test_ondemand<double>(str, [&](double actual) {
if(actual!=expected) {
std::cerr << "JSON '" << buf.data() << " parsed to ";
std::fprintf( stderr," %18.18g instead of %18.18g\n", actual, expected); // formatting numbers is easier with printf
@@ -137,7 +137,7 @@ TEST_SUCCEED();
#ifdef SIMDJSON_DEVELOPMENT_CHECKS
bool out_of_order_object_iteration_error() {
TEST_START();
auto json = R"([ { "x": 1, "y": 2 } ])"_padded;
std::string json = R"([ { "x": 1, "y": 2 } ])";
SUBTEST("simdjson_result<object>", test_ondemand_doc(json, [&](auto doc) {
for (auto element : doc) {
auto obj = element.get_object();
@@ -160,7 +160,7 @@ TEST_SUCCEED();
bool out_of_order_top_level_object_iteration_error() {
TEST_START();
auto json = R"({ "x": 1, "y": 2 })"_padded;
std::string json = R"({ "x": 1, "y": 2 })";
SUBTEST("simdjson_result<object>", test_ondemand_doc(json, [&](auto doc) {
auto obj = doc.get_object();
for (auto field : obj) { ASSERT_SUCCESS(field); }
@@ -179,7 +179,7 @@ TEST_SUCCEED();
bool out_of_order_object_index_child_error() {
TEST_START();
auto json = R"([ { "x": 1, "y": 2 } ])"_padded;
std::string json = R"([ { "x": 1, "y": 2 } ])";
SUBTEST("simdjson_result<object>", test_ondemand_doc(json, [&](auto doc) {
simdjson_result<ondemand::object> obj;
for (auto element : doc) {
@@ -221,7 +221,7 @@ TEST_SUCCEED();
bool out_of_order_object_index_sibling_error() {
TEST_START();
auto json = R"([ { "x": 0, "y": 2 }, { "x": 1, "y": 4 } ])"_padded;
std::string json = R"([ { "x": 0, "y": 2 }, { "x": 1, "y": 4 } ])";
SUBTEST("simdjson_result<object>", test_ondemand_doc(json, [&](auto doc) {
simdjson_result<ondemand::object> last_obj;
uint64_t i = 0;
@@ -300,7 +300,7 @@ TEST_SUCCEED();
bool out_of_order_object_find_field_child_error() {
TEST_START();
auto json = R"([ { "x": 1, "y": 2 } ])"_padded;
std::string json = R"([ { "x": 1, "y": 2 } ])";
SUBTEST("simdjson_result<object>", test_ondemand_doc(json, [&](auto doc) {
simdjson_result<ondemand::object> obj;
for (auto element : doc) {
@@ -342,7 +342,7 @@ TEST_SUCCEED();
bool out_of_order_object_find_field_sibling_error() {
TEST_START();
auto json = R"([ { "x": 0, "y": 2 }, { "x": 1, "y": 4 } ])"_padded;
std::string json = R"([ { "x": 0, "y": 2 }, { "x": 1, "y": 4 } ])";
SUBTEST("simdjson_result<object>", test_ondemand_doc(json, [&](auto doc) {
simdjson_result<ondemand::object> last_obj;
uint64_t i = 0;
@@ -421,7 +421,7 @@ TEST_SUCCEED();
bool out_of_order_object_find_field_unordered_child_error() {
TEST_START();
auto json = R"([ { "x": 1, "y": 2 } ])"_padded;
std::string json = R"([ { "x": 1, "y": 2 } ])";
SUBTEST("simdjson_result<object>", test_ondemand_doc(json, [&](auto doc) {
simdjson_result<ondemand::object> obj;
for (auto element : doc) {
@@ -463,7 +463,7 @@ TEST_SUCCEED();
bool out_of_order_object_find_field_unordered_sibling_error() {
TEST_START();
auto json = R"([ { "x": 0, "y": 2 }, { "x": 1, "y": 4 } ])"_padded;
std::string json = R"([ { "x": 0, "y": 2 }, { "x": 1, "y": 4 } ])";
SUBTEST("simdjson_result<object>", test_ondemand_doc(json, [&](auto doc) {
simdjson_result<ondemand::object> last_obj;
uint64_t i = 0;
@@ -9,7 +9,7 @@ namespace object_tests {
bool object_find_field_unordered() {
TEST_START();
auto json = R"({ "a": 1, "b": 2, "c/d": 3})"_padded;
std::string json = R"({ "a": 1, "b": 2, "c/d": 3})";
SUBTEST("ondemand::object", test_ondemand_doc(json, [&](auto doc_result) {
ondemand::object object;
ASSERT_SUCCESS( doc_result.get(object) );
@@ -39,7 +39,7 @@ namespace object_tests {
bool document_object_find_field_unordered() {
TEST_START();
auto json = R"({ "a": 1, "b": 2, "c/d": 3})"_padded;
std::string json = R"({ "a": 1, "b": 2, "c/d": 3})";
SUBTEST("ondemand::document", test_ondemand_doc(json, [&](auto doc_result) {
ondemand::document doc;
ASSERT_SUCCESS( std::move(doc_result).get(doc) );
@@ -65,7 +65,7 @@ namespace object_tests {
bool value_object_find_field_unordered() {
TEST_START();
auto json = R"({ "outer": { "a": 1, "b": 2, "c/d": 3 } })"_padded;
std::string json = R"({ "outer": { "a": 1, "b": 2, "c/d": 3 } })";
SUBTEST("ondemand::value", test_ondemand_doc(json, [&](auto doc_result) {
ondemand::value object;
ASSERT_SUCCESS( doc_result.find_field_unordered("outer").get(object) );
@@ -92,7 +92,7 @@ namespace object_tests {
bool object_find_field() {
TEST_START();
auto json = R"({ "a": 1, "b": 2, "c/d": 3})"_padded;
std::string json = R"({ "a": 1, "b": 2, "c/d": 3})";
SUBTEST("ondemand::object", test_ondemand_doc(json, [&](auto doc_result) {
ondemand::object object;
ASSERT_SUCCESS( doc_result.get(object) );
@@ -122,7 +122,7 @@ namespace object_tests {
bool document_object_find_field() {
TEST_START();
auto json = R"({ "a": 1, "b": 2, "c/d": 3})"_padded;
std::string json = R"({ "a": 1, "b": 2, "c/d": 3})";
SUBTEST("ondemand::document", test_ondemand_doc(json, [&](auto doc_result) {
ondemand::document doc;
ASSERT_SUCCESS( std::move(doc_result).get(doc) );
@@ -148,7 +148,7 @@ namespace object_tests {
bool value_object_find_field() {
TEST_START();
auto json = R"({ "outer": { "a": 1, "b": 2, "c/d": 3 } })"_padded;
std::string json = R"({ "outer": { "a": 1, "b": 2, "c/d": 3 } })";
SUBTEST("ondemand::value", test_ondemand_doc(json, [&](auto doc_result) {
ondemand::value object;
ASSERT_SUCCESS( doc_result.find_field("outer").get(object) );
+10 -10
View File
@@ -9,7 +9,7 @@ namespace object_tests {
bool object_index() {
TEST_START();
auto json = R"({ "a": 1, "b": 2, "c/d": 3})"_padded;
std::string json = R"({ "a": 1, "b": 2, "c/d": 3})";
SUBTEST("ondemand::object", test_ondemand_doc(json, [&](auto doc_result) {
ondemand::object object;
ASSERT_SUCCESS( doc_result.get(object) );
@@ -39,7 +39,7 @@ namespace object_tests {
bool document_object_index() {
TEST_START();
auto json = R"({ "a": 1, "b": 2, "c/d": 3})"_padded;
std::string json = R"({ "a": 1, "b": 2, "c/d": 3})";
SUBTEST("ondemand::document", test_ondemand_doc(json, [&](auto doc_result) {
ondemand::document doc;
ASSERT_SUCCESS( std::move(doc_result).get(doc) );
@@ -65,7 +65,7 @@ namespace object_tests {
bool value_object_index() {
TEST_START();
auto json = R"({ "outer": { "a": 1, "b": 2, "c/d": 3 } })"_padded;
std::string json = R"({ "outer": { "a": 1, "b": 2, "c/d": 3 } })";
SUBTEST("ondemand::value", test_ondemand_doc(json, [&](auto doc_result) {
ondemand::value object;
ASSERT_SUCCESS( doc_result["outer"].get(object) );
@@ -92,7 +92,7 @@ namespace object_tests {
bool document_nested_object_index() {
TEST_START();
auto json = R"({ "x": { "y": { "z": 2 } } }})"_padded;
std::string json = R"({ "x": { "y": { "z": 2 } } }})";
SUBTEST("simdjson_result<ondemand::document>", test_ondemand_doc(json, [&](auto doc_result) {
ASSERT_EQUAL( doc_result["x"]["y"]["z"].get_uint64().value_unsafe(), 2 );
return true;
@@ -108,7 +108,7 @@ namespace object_tests {
bool nested_object_index() {
TEST_START();
auto json = R"({ "x": { "y": { "z": 2 } } }})"_padded;
std::string json = R"({ "x": { "y": { "z": 2 } } }})";
SUBTEST("simdjson_result<ondemand::object>", test_ondemand_doc(json, [&](auto doc_result) {
simdjson_result<ondemand::object> object = doc_result.get_object();
ASSERT_EQUAL( object["x"]["y"]["z"].get_uint64().value_unsafe(), 2 );
@@ -125,7 +125,7 @@ namespace object_tests {
bool value_nested_object_index() {
TEST_START();
auto json = R"({ "x": { "y": { "z": 2 } } }})"_padded;
std::string json = R"({ "x": { "y": { "z": 2 } } }})";
SUBTEST("simdjson_result<ondemand::value>", test_ondemand_doc(json, [&](auto doc_result) {
simdjson_result<ondemand::value> x = doc_result["x"];
ASSERT_EQUAL( x["y"]["z"].get_uint64().value_unsafe(), 2 );
@@ -142,7 +142,7 @@ namespace object_tests {
bool object_index_partial_children() {
TEST_START();
auto json = R"(
std::string json = R"(
{
"scalar_ignore": 0,
"empty_array_ignore": [],
@@ -156,7 +156,7 @@ namespace object_tests {
"quadruple_nested_break": { "a": [ { "b": [ 9, 99 ], "c": 999 }, 9999 ], "d": 99999 },
"actual_value": 10
}
)"_padded;
)";
SUBTEST("ondemand::object", test_ondemand_doc(json, [&](auto doc_result) {
ondemand::object object;
ASSERT_SUCCESS( doc_result.get(object) );
@@ -385,7 +385,7 @@ namespace object_tests {
bool object_index_exception() {
TEST_START();
auto json = R"({ "a": 1, "b": 2, "c/d": 3})"_padded;
std::string json = R"({ "a": 1, "b": 2, "c/d": 3})";
SUBTEST("ondemand::object", test_ondemand_doc(json, [&](auto doc_result) {
ondemand::object object = doc_result;
@@ -399,7 +399,7 @@ namespace object_tests {
}
bool nested_object_index_exception() {
TEST_START();
auto json = R"({ "x": { "y": { "z": 2 } } }})"_padded;
std::string json = R"({ "x": { "y": { "z": 2 } } }})";
SUBTEST("simdjson_result<ondemand::document>", test_ondemand_doc(json, [&](auto doc_result) {
ASSERT_EQUAL( uint64_t(doc_result["x"]["y"]["z"]), 2 );
return true;
+2 -2
View File
@@ -8,7 +8,7 @@ namespace ordering_tests {
#if SIMDJSON_EXCEPTIONS
auto json = "{\"coordinates\":[{\"x\":1.1,\"y\":2.2,\"z\":3.3}]}"_padded;
std::string json = "{\"coordinates\":[{\"x\":1.1,\"y\":2.2,\"z\":3.3}]}";
bool in_order_object_index() {
TEST_START();
@@ -133,7 +133,7 @@ namespace ordering_tests {
bool use_object_multiple_times_out_of_order() {
TEST_START();
ondemand::parser parser{};
auto json2 = "{\"coordinates\":{\"x\":1.1,\"y\":2.2,\"z\":3.3}}"_padded;
std::string json2 = "{\"coordinates\":{\"x\":1.1,\"y\":2.2,\"z\":3.3}}";
auto doc = parser.iterate(json2);
auto x = doc["coordinates"]["x"];
auto y = doc["coordinates"]["y"];
+2 -2
View File
@@ -36,8 +36,8 @@ bool basics_3() {
ondemand::parser parser;
char json[3];
strcpy(json, "[1]");
ondemand::document doc = parser.iterate(json, strlen(json));
memcpy(json, "[1]", 3);
ondemand::document doc = parser.iterate(json, 3);
simdjson_unused auto unused_doc = doc.get_array();
+33 -33
View File
@@ -15,7 +15,7 @@ namespace scalar_tests {
template<> json_type expected_json_type<bool>() { return json_type::boolean; }
template<typename T>
bool test_scalar_value(const padded_string &json, const T &expected, bool test_twice=true) {
bool test_scalar_value(const std::string &json, const T &expected, bool test_twice=true) {
std::cout << "- JSON: " << json << endl;
SUBTEST( "simdjson_result<document>", test_ondemand_doc(json, [&](auto doc_result) {
T actual;
@@ -47,7 +47,7 @@ namespace scalar_tests {
}));
{
padded_string whitespace_json = std::string(json) + " ";
std::string whitespace_json = std::string(json) + " ";
std::cout << "- JSON: " << whitespace_json << endl;
SUBTEST( "simdjson_result<document>", test_ondemand_doc(whitespace_json, [&](auto doc_result) {
T actual;
@@ -80,7 +80,7 @@ namespace scalar_tests {
}
{
padded_string array_json = std::string("[") + std::string(json) + "]";
std::string array_json = std::string("[") + std::string(json) + "]";
std::cout << "- JSON: " << array_json << endl;
SUBTEST( "simdjson_result<value>", test_ondemand_doc(array_json, [&](auto doc_result) {
int count = 0;
@@ -123,7 +123,7 @@ namespace scalar_tests {
}
{
padded_string whitespace_array_json = std::string("[") + std::string(json) + " ]";
std::string whitespace_array_json = std::string("[") + std::string(json) + " ]";
std::cout << "- JSON: " << whitespace_array_json << endl;
SUBTEST( "simdjson_result<value>", test_ondemand_doc(whitespace_array_json, [&](auto doc_result) {
@@ -173,36 +173,36 @@ namespace scalar_tests {
bool string_value() {
TEST_START();
// We can't retrieve a small string twice because it will blow out the string buffer
if (!test_scalar_value(R"("hi")"_padded, std::string_view("hi"), false)) { return false; }
if (!test_scalar_value(R"("hi")", std::string_view("hi"), false)) { return false; }
// ... unless the document is big enough to have a big string buffer :)
if (!test_scalar_value(R"("hi" )"_padded, std::string_view("hi"))) { return false; }
if (!test_scalar_value(R"("hi" )", std::string_view("hi"))) { return false; }
TEST_SUCCEED();
}
bool numeric_values() {
TEST_START();
if (!test_scalar_value<int64_t> ("0"_padded, 0)) { return false; }
if (!test_scalar_value<uint64_t>("0"_padded, 0)) { return false; }
if (!test_scalar_value<double> ("0"_padded, 0)) { return false; }
if (!test_scalar_value<int64_t> ("1"_padded, 1)) { return false; }
if (!test_scalar_value<uint64_t>("1"_padded, 1)) { return false; }
if (!test_scalar_value<double> ("1"_padded, 1)) { return false; }
if (!test_scalar_value<int64_t> ("-1"_padded, -1)) { return false; }
if (!test_scalar_value<double> ("-1"_padded, -1)) { return false; }
if (!test_scalar_value<double> ("1.1"_padded, 1.1)) { return false; }
if (!test_scalar_value<int64_t> ("0", 0)) { return false; }
if (!test_scalar_value<uint64_t>("0", 0)) { return false; }
if (!test_scalar_value<double> ("0", 0)) { return false; }
if (!test_scalar_value<int64_t> ("1", 1)) { return false; }
if (!test_scalar_value<uint64_t>("1", 1)) { return false; }
if (!test_scalar_value<double> ("1", 1)) { return false; }
if (!test_scalar_value<int64_t> ("-1", -1)) { return false; }
if (!test_scalar_value<double> ("-1", -1)) { return false; }
if (!test_scalar_value<double> ("1.1", 1.1)) { return false; }
TEST_SUCCEED();
}
bool boolean_values() {
TEST_START();
if (!test_scalar_value<bool> ("true"_padded, true)) { return false; }
if (!test_scalar_value<bool> ("false"_padded, false)) { return false; }
if (!test_scalar_value<bool> ("true", true)) { return false; }
if (!test_scalar_value<bool> ("false", false)) { return false; }
TEST_SUCCEED();
}
bool null_value() {
TEST_START();
auto json = "null"_padded;
std::string json = "null";
SUBTEST("ondemand::document", test_ondemand_doc(json, [&](auto doc_result) {
ondemand::document doc;
ASSERT_SUCCESS( std::move(doc_result).get(doc) );
@@ -213,7 +213,7 @@ namespace scalar_tests {
ASSERT_EQUAL( doc_result.is_null(), true );
return true;
}));
json = "[null]"_padded;
json = "[null]";
SUBTEST("ondemand::value", test_ondemand_doc(json, [&](auto doc_result) {
int count = 0;
for (auto value_result : doc_result) {
@@ -240,7 +240,7 @@ namespace scalar_tests {
#if SIMDJSON_EXCEPTIONS
template<typename T>
bool test_scalar_value_exception(const padded_string &json, const T &expected) {
bool test_scalar_value_exception(const std::string &json, const T &expected) {
std::cout << "- JSON: " << json << endl;
SUBTEST( "document", test_ondemand_doc(json, [&](auto doc_result) {
ondemand::document doc;
@@ -248,7 +248,7 @@ namespace scalar_tests {
ASSERT_EQUAL( expected, T(doc) );
return true;
}));
padded_string array_json = std::string("[") + std::string(json) + "]";
std::string array_json = std::string("[") + std::string(json) + "]";
std::cout << "- JSON: " << array_json << endl;
SUBTEST( "value", test_ondemand_doc(array_json, [&](auto doc_result) {
int count = 0;
@@ -263,27 +263,27 @@ namespace scalar_tests {
}
bool string_value_exception() {
TEST_START();
return test_scalar_value_exception(R"("hi")"_padded, std::string_view("hi"));
return test_scalar_value_exception(R"("hi")", std::string_view("hi"));
}
bool numeric_values_exception() {
TEST_START();
if (!test_scalar_value_exception<int64_t> ("0"_padded, 0)) { return false; }
if (!test_scalar_value_exception<uint64_t>("0"_padded, 0)) { return false; }
if (!test_scalar_value_exception<double> ("0"_padded, 0)) { return false; }
if (!test_scalar_value_exception<int64_t> ("1"_padded, 1)) { return false; }
if (!test_scalar_value_exception<uint64_t>("1"_padded, 1)) { return false; }
if (!test_scalar_value_exception<double> ("1"_padded, 1)) { return false; }
if (!test_scalar_value_exception<int64_t> ("-1"_padded, -1)) { return false; }
if (!test_scalar_value_exception<double> ("-1"_padded, -1)) { return false; }
if (!test_scalar_value_exception<double> ("1.1"_padded, 1.1)) { return false; }
if (!test_scalar_value_exception<int64_t> ("0", 0)) { return false; }
if (!test_scalar_value_exception<uint64_t>("0", 0)) { return false; }
if (!test_scalar_value_exception<double> ("0", 0)) { return false; }
if (!test_scalar_value_exception<int64_t> ("1", 1)) { return false; }
if (!test_scalar_value_exception<uint64_t>("1", 1)) { return false; }
if (!test_scalar_value_exception<double> ("1", 1)) { return false; }
if (!test_scalar_value_exception<int64_t> ("-1", -1)) { return false; }
if (!test_scalar_value_exception<double> ("-1", -1)) { return false; }
if (!test_scalar_value_exception<double> ("1.1", 1.1)) { return false; }
TEST_SUCCEED();
}
bool boolean_values_exception() {
TEST_START();
if (!test_scalar_value_exception<bool> ("true"_padded, true)) { return false; }
if (!test_scalar_value_exception<bool> ("false"_padded, false)) { return false; }
if (!test_scalar_value_exception<bool> ("true", true)) { return false; }
if (!test_scalar_value_exception<bool> ("false", false)) { return false; }
TEST_SUCCEED();
}
+12 -6
View File
@@ -11,7 +11,8 @@ namespace twitter_tests {
TEST_START();
padded_string json;
ASSERT_SUCCESS( padded_string::load(TWITTER_JSON).get(json) );
ASSERT_TRUE(test_ondemand_doc(json, [&](auto doc_result) {
std::string json_str(json);
ASSERT_TRUE(test_ondemand_doc(json_str, [&](auto doc_result) {
uint64_t count;
ASSERT_SUCCESS( doc_result["search_metadata"]["count"].get(count) );
ASSERT_EQUAL( count, 100 );
@@ -46,7 +47,8 @@ namespace twitter_tests {
TEST_START();
padded_string json;
ASSERT_SUCCESS( padded_string::load(TWITTER_JSON).get(json) );
ASSERT_TRUE(test_ondemand_doc(json, [&](auto doc_result) {
std::string json_str = json.to_string();
ASSERT_TRUE(test_ondemand_doc(json_str, [&](auto doc_result) {
// Print users with a default profile.
set<string_view> default_users;
for (auto tweet : doc_result["statuses"]) {
@@ -72,7 +74,8 @@ namespace twitter_tests {
TEST_START();
padded_string json;
ASSERT_SUCCESS( padded_string::load(TWITTER_JSON).get(json) );
ASSERT_TRUE(test_ondemand_doc(json, [&](auto doc_result) {
std::string json_str = json.to_string();
ASSERT_TRUE(test_ondemand_doc(json_str, [&](auto doc_result) {
// Print image names and sizes
set<pair<uint64_t, uint64_t>> image_sizes;
for (auto tweet : doc_result["statuses"]) {
@@ -111,7 +114,8 @@ namespace twitter_tests {
TEST_START();
padded_string json;
ASSERT_SUCCESS( padded_string::load(TWITTER_JSON).get(json) );
ASSERT_TRUE(test_ondemand_doc(json, [&](auto doc_result) {
std::string json_str = json.to_string();
ASSERT_TRUE(test_ondemand_doc(json_str, [&](auto doc_result) {
uint64_t count = doc_result["search_metadata"]["count"];
ASSERT_EQUAL( count, 100 );
return true;
@@ -122,7 +126,8 @@ namespace twitter_tests {
bool twitter_default_profile_exception() {
TEST_START();
padded_string json = padded_string::load(TWITTER_JSON);
ASSERT_TRUE(test_ondemand_doc(json, [&](auto doc_result) {
std::string json_str = json.to_string();
ASSERT_TRUE(test_ondemand_doc(json_str, [&](auto doc_result) {
// Print users with a default profile.
set<string_view> default_users;
for (auto tweet : doc_result["statuses"]) {
@@ -151,7 +156,8 @@ namespace twitter_tests {
bool twitter_image_sizes_exception() {
TEST_START();
padded_string json = padded_string::load(TWITTER_JSON);
ASSERT_TRUE(test_ondemand_doc(json, [&](auto doc_result) {
std::string json_str = json.to_string();
ASSERT_TRUE(test_ondemand_doc(json_str, [&](auto doc_result) {
// Print image names and sizes
set<pair<uint64_t, uint64_t>> image_sizes;
for (auto tweet : doc_result["statuses"]) {
@@ -9,9 +9,8 @@ namespace wrong_type_error_tests {
#define TEST_CAST_ERROR(JSON, TYPE, ERROR) \
std::cout << "- Subtest: get_" << (#TYPE) << "() - JSON: " << (JSON) << std::endl; \
{ \
/* Put padding into the string to check the buffer overrun code as well */ \
auto doc_json = std::string(JSON) + "1111111111111111111111111111111111111111111111111111111111111111"; \
if (!test_ondemand_doc(padded_string_view(doc_json.data(), strlen(JSON), doc_json.length()), [&](auto doc_result) { \
std::string doc_json = std::string(JSON); \
if (!test_ondemand_doc(doc_json, [&](auto doc_result) { \
ASSERT_ERROR( doc_result.get_##TYPE(), (ERROR) ); \
return true; \
})) { \
@@ -19,7 +18,7 @@ namespace wrong_type_error_tests {
} \
} \
{ \
padded_string a_json(std::string(R"({ "a": )") + JSON + " }"); \
std::string a_json(std::string(R"({ "a": )") + JSON + " }"); \
std::cout << R"(- Subtest: get_)" << (#TYPE) << "() - JSON: " << a_json << std::endl; \
if (!test_ondemand_doc(a_json, [&](auto doc_result) { \
ASSERT_ERROR( doc_result["a"].get_##TYPE(), (ERROR) ); \
+5 -5
View File
@@ -7,24 +7,24 @@
#include "test_macros.h"
template<typename T, typename F>
bool test_ondemand(simdjson::ondemand::parser &parser, const simdjson::padded_string &json, const F& f) {
bool test_ondemand(simdjson::ondemand::parser &parser, const std::string &json, const F& f) {
auto doc = parser.iterate(json);
T val;
ASSERT_SUCCESS( doc.get(val) );
return f(val);
}
template<typename T, typename F>
bool test_ondemand(const simdjson::padded_string &json, const F& f) {
bool test_ondemand(const std::string &json, const F& f) {
simdjson::ondemand::parser parser;
return test_ondemand<T, F>(parser, json, f);
}
template<typename F>
bool test_ondemand_doc(simdjson::ondemand::parser &parser, const simdjson::padded_string &json, const F& f) {
bool test_ondemand_doc(simdjson::ondemand::parser &parser, const std::string &json, const F& f) {
return f(parser.iterate(json));
}
template<typename F>
bool test_ondemand_doc(const simdjson::padded_string &json, const F& f) {
bool test_ondemand_doc(const std::string &json, const F& f) {
simdjson::ondemand::parser parser;
return test_ondemand_doc(parser, json, f);
}
@@ -32,7 +32,7 @@ bool test_ondemand_doc(const simdjson::padded_string &json, const F& f) {
#define ONDEMAND_SUBTEST(NAME, JSON, TEST) \
{ \
std::cout << "- Subtest " << NAME << " - JSON: " << (JSON) << " ..." << std::endl; \
if (!test_ondemand_doc(JSON##_padded, [&](auto doc) { \
if (!test_ondemand_doc(JSON##s, [&](auto doc) { \
return (TEST); \
})) { \
return false; \