Add actual examples from basics.md to readme_examples

This commit is contained in:
John Keiser
2020-03-29 16:12:38 -07:00
parent 835b640ebd
commit 7ed65e42d7
8 changed files with 474 additions and 398 deletions
+2
View File
@@ -103,6 +103,7 @@ objs
/perfdiff
/pointercheck
/readme_examples
/readme_examples_noexceptions
/statisticalmodel
/stringparsingcheck
/submodules
@@ -119,6 +120,7 @@ objs
/tests/integer_tests
/tests/parse_many_test
/tests/readme_examples
/tests/readme_examples_noexceptions
/tools/json2json
/tools/jsonstats
/tools/minify
+4 -5
View File
@@ -91,7 +91,7 @@ JSON_INCLUDE:=dependencies/json/single_include/nlohmann/json.hpp
EXTRAOBJECTS=ujdecode.o
MAINEXECUTABLES=parse minify json2json jsonstats statisticalmodel jsonpointer get_corpus_benchmark
TESTEXECUTABLES=jsoncheck jsoncheck_westmere jsoncheck_fallback integer_tests numberparsingcheck stringparsingcheck pointercheck parse_many_test basictests errortests readme_examples
TESTEXECUTABLES=jsoncheck jsoncheck_westmere jsoncheck_fallback integer_tests numberparsingcheck stringparsingcheck pointercheck parse_many_test basictests errortests readme_examples readme_examples_noexceptions
COMPARISONEXECUTABLES=minifiercompetition parsingcompetition parseandstatcompetition distinctuseridcompetition allparserscheckfile allparsingcompetition
SUPPLEMENTARYEXECUTABLES=parse_noutf8validation parse_nonumberparsing parse_nostringparsing
@@ -111,9 +111,6 @@ run_basictests: basictests
run_errortests: errortests
./errortests
run_readme_examples: readme_examples
./readme_examples
run_numberparsingcheck: numberparsingcheck
./numberparsingcheck
@@ -161,7 +158,7 @@ test: quicktests slowtests
quiettest: quicktests slowtests
quicktests: run_basictests run_quickstart run_readme_examples run_jsoncheck run_numberparsingcheck run_integer_tests run_stringparsingcheck run_jsoncheck run_parse_many_test run_pointercheck run_jsoncheck_westmere run_jsoncheck_fallback
quicktests: run_basictests run_quickstart readme_examples readme_examples_noexceptions run_jsoncheck run_numberparsingcheck run_integer_tests run_stringparsingcheck run_jsoncheck run_parse_many_test run_pointercheck run_jsoncheck_westmere run_jsoncheck_fallback
slowtests: run_testjson2json_sh run_issue150_sh
@@ -234,6 +231,8 @@ errortests:tests/errortests.cpp $(HEADERS) $(LIBFILES)
readme_examples: tests/readme_examples.cpp $(HEADERS) $(LIBFILES)
$(CXX) $(CXXFLAGS) -o readme_examples tests/readme_examples.cpp -I. $(LIBFILES) $(LIBFLAGS)
readme_examples_noexceptions: tests/readme_examples_noexceptions.cpp $(HEADERS) $(LIBFILES)
$(CXX) $(CXXFLAGS) -o readme_examples_noexceptions tests/readme_examples_noexceptions.cpp -I. $(LIBFILES) $(LIBFLAGS) -fno-exceptions
numberparsingcheck: tests/numberparsingcheck.cpp $(HEADERS) src/simdjson.cpp
$(CXX) $(CXXFLAGS) -o numberparsingcheck tests/numberparsingcheck.cpp -I. $(LIBFLAGS) -DJSON_TEST_NUMBERS
+36 -35
View File
@@ -102,8 +102,6 @@ for (dom::object car : cars) {
}
```
JSON Pointer
------------
@@ -144,7 +142,7 @@ behavior.
>
> ```c++
> dom::element doc;
> error_code error;
> simdjson::error_code error;
> parser.parse(json).tie(doc, error); // <-- Assigns to doc and error just like "auto [doc, error]"
> ```
@@ -154,48 +152,50 @@ This is how the example in "Using the Parsed JSON" could be written using only e
```c++
auto 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 ] }
{ "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;
auto [doc, error] = parser.parse(cars_json);
auto [cars, error] = parser.parse(cars_json).get<dom::array>();
if (error) { cerr << error << endl; exit(1); }
// Iterating through an array of objects
for (dom::element car_element : cars) {
dom::object car;
car_element.get<dom::object>().tie(car, error);
if (error) { cerr << error << endl; exit(1); }
dom::object car;
car_element.get<dom::object>().tie(car, error);
if (error) { cerr << error << endl; exit(1); }
// Accessing a field by name
dom::element make, model;
car["make"].tie(make, error);
if (error) { cerr << error << endl; exit(1); }
car["model"].tie(model, error);
if (error) { cerr << error << endl; exit(1); }
cout << "Make/Model: " << make << "/" << model << endl;
// Accessing a field by name
dom::element make, model;
car["make"].tie(make, error);
if (error) { cerr << error << endl; exit(1); }
car["model"].tie(model, error);
if (error) { cerr << error << endl; exit(1); }
cout << "Make/Model: " << make << "/" << model << endl;
// Casting a JSON element to an integer
uint64_t year;
car["year"].get<uint64_t>().tie(year, error);
if (error) { cerr << error << endl; exit(1); }
cout << "- This car is " << 2020 - year << "years old." << endl;
// Casting a JSON element to an integer
uint64_t year;
car["year"].get<uint64_t>().tie(year, error);
if (error) { cerr << error << endl; exit(1); }
cout << "- This car is " << 2020 - year << "years old." << endl;
// Iterating through an array of floats
double total_tire_pressure = 0;
for (dom::element tire_pressure_element : car["tire_pressure"]) {
// Iterating through an array of floats
double total_tire_pressure = 0;
dom::array tire_pressure_array;
car["tire_pressure"].get<dom::array>().tie(tire_pressure_array, error);
if (error) { cerr << error << endl; exit(1); }
for (dom::element tire_pressure_element : tire_pressure_array) {
double tire_pressure;
tire_pressure_element.get<uint64_t>().tie(tire_pressure, error);
tire_pressure_element.get<double>().tie(tire_pressure, error);
if (error) { cerr << error << endl; exit(1); }
total_tire_pressure += tire_pressure;
}
cout << "- Average tire pressure: " << (total_tire_pressure / 4) << endl;
}
cout << "- Average tire pressure: " << (total_tire_pressure / 4) << endl;
// Writing out all the information about the car
for (auto [key, value] : car) {
// Writing out all the information about the car
for (auto [key, value] : car) {
cout << "- " << key << ": " << value << endl;
}
}
```
@@ -215,14 +215,15 @@ Newline-Delimited JSON (ndjson) and JSON lines
The simdjson library also support multithreaded JSON streaming through a large file containing many smaller JSON documents in either [ndjson](http://ndjson.org) or [JSON lines](http://jsonlines.org) format. If your JSON documents all contain arrays or objects, we even support direct file concatenation without whitespace. The concatenated file has no size restrictions (including larger than 4GB), though each individual document must be less than 4GB.
Here is a simple example:
Here is a simple example, given "x.json" with this content:
```cpp
auto ndjson = R"(
```json
{ "foo": 1 }
{ "foo": 2 }
{ "foo": 3 }
)"_padded;
```
```c++
dom::parser parser;
for (dom::element doc : parser.load_many(filename)) {
cout << doc["foo"] << endl;
+276 -257
View File
@@ -85,263 +85,6 @@ class tape_ref;
namespace simdjson::dom {
/**
* A parsed JSON document.
*
* This class cannot be copied, only moved, to avoid unintended allocations.
*/
class document {
public:
/**
* Create a document container with zero capacity.
*
* The parser will allocate capacity as needed.
*/
document() noexcept=default;
~document() noexcept=default;
/**
* Take another document's buffers.
*
* @param other The document to take. Its capacity is zeroed and it is invalidated.
*/
document(document &&other) noexcept = default;
document(const document &) = delete; // Disallow copying
/**
* Take another document's buffers.
*
* @param other The document to take. Its capacity is zeroed.
*/
document &operator=(document &&other) noexcept = default;
document &operator=(const document &) = delete; // Disallow copying
/**
* Get the root element of this document as a JSON array.
*/
element root() const noexcept;
/**
* Dump the raw tape for debugging.
*
* @param os the stream to output to.
* @return false if the tape is likely wrong (e.g., you did not parse a valid JSON).
*/
bool dump_raw_tape(std::ostream &os) const noexcept;
std::unique_ptr<uint64_t[]> tape;
std::unique_ptr<uint8_t[]> string_buf;// should be at least byte_capacity
private:
inline error_code set_capacity(size_t len) noexcept;
template<typename T>
friend class simdjson::minify;
friend class parser;
}; // class document
/**
* A JSON element.
*
* References an element in a JSON document, representing a JSON null, boolean, string, number,
* array or object.
*/
class element : protected internal::tape_ref {
public:
/** Create a new, invalid element. */
really_inline element() noexcept;
/** Whether this element is a json `null`. */
really_inline bool is_null() const noexcept;
/**
* Tell whether the value can be cast to the given primitive type.
*
* Supported types:
* - Boolean: bool
* - Number: double, uint64_t, int64_t
* - String: std::string_view, const char *
* - Array: array
*/
template<typename T>
really_inline bool is() const noexcept;
/**
* Get the value as the given primitive type.
*
* Supported types:
* - Boolean: bool
* - Number: double, uint64_t, int64_t
* - String: std::string_view, const char *
* - Array: array
*
* @returns The value cast to the given type, or:
* INCORRECT_TYPE if the value cannot be cast to the given type.
*/
template<typename T>
really_inline simdjson_result<T> get() const noexcept;
#if SIMDJSON_EXCEPTIONS
/**
* Read this element as a boolean.
*
* @return The boolean value
* @exception simdjson_error(UNEXPECTED_TYPE) if the JSON element is not a boolean.
*/
inline operator bool() const noexcept(false);
/**
* Read this element as a null-terminated string.
*
* Does *not* convert other types to a string; requires that the JSON type of the element was
* an actual string.
*
* @return The string value.
* @exception simdjson_error(UNEXPECTED_TYPE) if the JSON element is not a string.
*/
inline explicit operator const char*() const noexcept(false);
/**
* Read this element as a null-terminated string.
*
* Does *not* convert other types to a string; requires that the JSON type of the element was
* an actual string.
*
* @return The string value.
* @exception simdjson_error(UNEXPECTED_TYPE) if the JSON element is not a string.
*/
inline operator std::string_view() const noexcept(false);
/**
* Read this element as an unsigned integer.
*
* @return The integer value.
* @exception simdjson_error(UNEXPECTED_TYPE) if the JSON element is not an integer
* @exception simdjson_error(NUMBER_OUT_OF_RANGE) if the integer doesn't fit in 64 bits or is negative
*/
inline operator uint64_t() const noexcept(false);
/**
* Read this element as an signed integer.
*
* @return The integer value.
* @exception simdjson_error(UNEXPECTED_TYPE) if the JSON element is not an integer
* @exception simdjson_error(NUMBER_OUT_OF_RANGE) if the integer doesn't fit in 64 bits
*/
inline operator int64_t() const noexcept(false);
/**
* Read this element as an double.
*
* @return The double value.
* @exception simdjson_error(UNEXPECTED_TYPE) if the JSON element is not a number
* @exception simdjson_error(NUMBER_OUT_OF_RANGE) if the integer doesn't fit in 64 bits or is negative
*/
inline operator double() const noexcept(false);
/**
* Read this element as a JSON array.
*
* @return The JSON array.
* @exception simdjson_error(UNEXPECTED_TYPE) if the JSON element is not an array
*/
inline operator array() const noexcept(false);
/**
* Read this element as a JSON object (key/value pairs).
*
* @return The JSON object.
* @exception simdjson_error(UNEXPECTED_TYPE) if the JSON element is not an object
*/
inline operator object() const noexcept(false);
#endif // SIMDJSON_EXCEPTIONS
/**
* Get the value associated with the given key.
*
* The key will be matched against **unescaped** JSON:
*
* dom::parser parser;
* parser.parse(R"({ "a\n": 1 })")["a\n"].get<uint64_t>().value == 1
* parser.parse(R"({ "a\n": 1 })")["a\\n"].get<uint64_t>().error == NO_SUCH_FIELD
*
* @return The value associated with this field, or:
* - NO_SUCH_FIELD if the field does not exist in the object
* - INCORRECT_TYPE if this is not an object
*/
inline simdjson_result<element> operator[](const std::string_view &key) const noexcept;
/**
* Get the value associated with the given key.
*
* The key will be matched against **unescaped** JSON:
*
* dom::parser parser;
* parser.parse(R"({ "a\n": 1 })")["a\n"].get<uint64_t>().value == 1
* parser.parse(R"({ "a\n": 1 })")["a\\n"].get<uint64_t>().error == NO_SUCH_FIELD
*
* @return The value associated with this field, or:
* - NO_SUCH_FIELD if the field does not exist in the object
* - INCORRECT_TYPE if this is not an object
*/
inline simdjson_result<element> operator[](const char *key) const noexcept;
/**
* Get the value associated with the given JSON pointer.
*
* dom::parser parser;
* element doc = parser.parse(R"({ "foo": { "a": [ 10, 20, 30 ] }})");
* doc.at("/foo/a/1") == 20
* doc.at("/")["foo"]["a"].at(1) == 20
* doc.at("")["foo"]["a"].at(1) == 20
*
* @return The value associated with the given JSON pointer, or:
* - NO_SUCH_FIELD if a field does not exist in an object
* - INDEX_OUT_OF_BOUNDS if an array index is larger than an array length
* - INCORRECT_TYPE if a non-integer is used to access an array
* - INVALID_JSON_POINTER if the JSON pointer is invalid and cannot be parsed
*/
inline simdjson_result<element> at(const std::string_view &json_pointer) const noexcept;
/**
* Get the value at the given index.
*
* @return The value at the given index, or:
* - INDEX_OUT_OF_BOUNDS if the array index is larger than an array length
*/
inline simdjson_result<element> at(size_t index) const noexcept;
/**
* Get the value associated with the given key.
*
* The key will be matched against **unescaped** JSON:
*
* dom::parser parser;
* parser.parse(R"({ "a\n": 1 })")["a\n"].get<uint64_t>().value == 1
* parser.parse(R"({ "a\n": 1 })")["a\\n"].get<uint64_t>().error == NO_SUCH_FIELD
*
* @return The value associated with this field, or:
* - NO_SUCH_FIELD if the field does not exist in the object
*/
inline simdjson_result<element> at_key(const std::string_view &key) const noexcept;
/**
* Get the value associated with the given key in a case-insensitive manner.
*
* Note: The key will be matched against **unescaped** JSON.
*
* @return The value associated with this field, or:
* - NO_SUCH_FIELD if the field does not exist in the object
*/
inline simdjson_result<element> at_key_case_insensitive(const std::string_view &key) const noexcept;
/** @private for debugging. Prints out the root element. */
inline bool dump_raw_tape(std::ostream &out) const noexcept;
private:
really_inline element(const document *doc, size_t json_index) noexcept;
friend class document;
friend class object;
friend class array;
friend struct simdjson_result<element>;
template<typename T>
friend class simdjson::minify;
};
/**
* Represents a JSON array.
*/
@@ -552,6 +295,279 @@ private:
friend class simdjson::minify;
};
/**
* A parsed JSON document.
*
* This class cannot be copied, only moved, to avoid unintended allocations.
*/
class document {
public:
/**
* Create a document container with zero capacity.
*
* The parser will allocate capacity as needed.
*/
document() noexcept=default;
~document() noexcept=default;
/**
* Take another document's buffers.
*
* @param other The document to take. Its capacity is zeroed and it is invalidated.
*/
document(document &&other) noexcept = default;
document(const document &) = delete; // Disallow copying
/**
* Take another document's buffers.
*
* @param other The document to take. Its capacity is zeroed.
*/
document &operator=(document &&other) noexcept = default;
document &operator=(const document &) = delete; // Disallow copying
/**
* Get the root element of this document as a JSON array.
*/
element root() const noexcept;
/**
* Dump the raw tape for debugging.
*
* @param os the stream to output to.
* @return false if the tape is likely wrong (e.g., you did not parse a valid JSON).
*/
bool dump_raw_tape(std::ostream &os) const noexcept;
std::unique_ptr<uint64_t[]> tape;
std::unique_ptr<uint8_t[]> string_buf;// should be at least byte_capacity
private:
inline error_code set_capacity(size_t len) noexcept;
template<typename T>
friend class simdjson::minify;
friend class parser;
}; // class document
/**
* A JSON element.
*
* References an element in a JSON document, representing a JSON null, boolean, string, number,
* array or object.
*/
class element : protected internal::tape_ref {
public:
/** Create a new, invalid element. */
really_inline element() noexcept;
/** Whether this element is a json `null`. */
really_inline bool is_null() const noexcept;
/**
* Tell whether the value can be cast to the given primitive type.
*
* Supported types:
* - Boolean: bool
* - Number: double, uint64_t, int64_t
* - String: std::string_view, const char *
* - Array: array
*/
template<typename T>
really_inline bool is() const noexcept;
/**
* Get the value as the given primitive type.
*
* Supported types:
* - Boolean: bool
* - Number: double, uint64_t, int64_t
* - String: std::string_view, const char *
* - Array: array
*
* @returns The value cast to the given type, or:
* INCORRECT_TYPE if the value cannot be cast to the given type.
*/
template<typename T>
really_inline simdjson_result<T> get() const noexcept;
#if SIMDJSON_EXCEPTIONS
/**
* Read this element as a boolean.
*
* @return The boolean value
* @exception simdjson_error(INCORRECT_TYPE) if the JSON element is not a boolean.
*/
inline operator bool() const noexcept(false);
/**
* Read this element as a null-terminated string.
*
* Does *not* convert other types to a string; requires that the JSON type of the element was
* an actual string.
*
* @return The string value.
* @exception simdjson_error(INCORRECT_TYPE) if the JSON element is not a string.
*/
inline explicit operator const char*() const noexcept(false);
/**
* Read this element as a null-terminated string.
*
* Does *not* convert other types to a string; requires that the JSON type of the element was
* an actual string.
*
* @return The string value.
* @exception simdjson_error(INCORRECT_TYPE) if the JSON element is not a string.
*/
inline operator std::string_view() const noexcept(false);
/**
* Read this element as an unsigned integer.
*
* @return The integer value.
* @exception simdjson_error(INCORRECT_TYPE) if the JSON element is not an integer
* @exception simdjson_error(NUMBER_OUT_OF_RANGE) if the integer doesn't fit in 64 bits or is negative
*/
inline operator uint64_t() const noexcept(false);
/**
* Read this element as an signed integer.
*
* @return The integer value.
* @exception simdjson_error(INCORRECT_TYPE) if the JSON element is not an integer
* @exception simdjson_error(NUMBER_OUT_OF_RANGE) if the integer doesn't fit in 64 bits
*/
inline operator int64_t() const noexcept(false);
/**
* Read this element as an double.
*
* @return The double value.
* @exception simdjson_error(INCORRECT_TYPE) if the JSON element is not a number
* @exception simdjson_error(NUMBER_OUT_OF_RANGE) if the integer doesn't fit in 64 bits or is negative
*/
inline operator double() const noexcept(false);
/**
* Read this element as a JSON array.
*
* @return The JSON array.
* @exception simdjson_error(INCORRECT_TYPE) if the JSON element is not an array
*/
inline operator array() const noexcept(false);
/**
* Read this element as a JSON object (key/value pairs).
*
* @return The JSON object.
* @exception simdjson_error(INCORRECT_TYPE) if the JSON element is not an object
*/
inline operator object() const noexcept(false);
/**
* Iterate over each element in this array.
*
* @return The beginning of the iteration.
* @exception simdjson_error(INCORRECT_TYPE) if the JSON element is not an array
*/
inline dom::array::iterator begin() const noexcept(false);
/**
* Iterate over each element in this array.
*
* @return The end of the iteration.
* @exception simdjson_error(INCORRECT_TYPE) if the JSON element is not an array
*/
inline dom::array::iterator end() const noexcept(false);
#endif // SIMDJSON_EXCEPTIONS
/**
* Get the value associated with the given key.
*
* The key will be matched against **unescaped** JSON:
*
* dom::parser parser;
* parser.parse(R"({ "a\n": 1 })")["a\n"].get<uint64_t>().value == 1
* parser.parse(R"({ "a\n": 1 })")["a\\n"].get<uint64_t>().error == NO_SUCH_FIELD
*
* @return The value associated with this field, or:
* - NO_SUCH_FIELD if the field does not exist in the object
* - INCORRECT_TYPE if this is not an object
*/
inline simdjson_result<element> operator[](const std::string_view &key) const noexcept;
/**
* Get the value associated with the given key.
*
* The key will be matched against **unescaped** JSON:
*
* dom::parser parser;
* parser.parse(R"({ "a\n": 1 })")["a\n"].get<uint64_t>().value == 1
* parser.parse(R"({ "a\n": 1 })")["a\\n"].get<uint64_t>().error == NO_SUCH_FIELD
*
* @return The value associated with this field, or:
* - NO_SUCH_FIELD if the field does not exist in the object
* - INCORRECT_TYPE if this is not an object
*/
inline simdjson_result<element> operator[](const char *key) const noexcept;
/**
* Get the value associated with the given JSON pointer.
*
* dom::parser parser;
* element doc = parser.parse(R"({ "foo": { "a": [ 10, 20, 30 ] }})");
* doc.at("/foo/a/1") == 20
* doc.at("/")["foo"]["a"].at(1) == 20
* doc.at("")["foo"]["a"].at(1) == 20
*
* @return The value associated with the given JSON pointer, or:
* - NO_SUCH_FIELD if a field does not exist in an object
* - INDEX_OUT_OF_BOUNDS if an array index is larger than an array length
* - INCORRECT_TYPE if a non-integer is used to access an array
* - INVALID_JSON_POINTER if the JSON pointer is invalid and cannot be parsed
*/
inline simdjson_result<element> at(const std::string_view &json_pointer) const noexcept;
/**
* Get the value at the given index.
*
* @return The value at the given index, or:
* - INDEX_OUT_OF_BOUNDS if the array index is larger than an array length
*/
inline simdjson_result<element> at(size_t index) const noexcept;
/**
* Get the value associated with the given key.
*
* The key will be matched against **unescaped** JSON:
*
* dom::parser parser;
* parser.parse(R"({ "a\n": 1 })")["a\n"].get<uint64_t>().value == 1
* parser.parse(R"({ "a\n": 1 })")["a\\n"].get<uint64_t>().error == NO_SUCH_FIELD
*
* @return The value associated with this field, or:
* - NO_SUCH_FIELD if the field does not exist in the object
*/
inline simdjson_result<element> at_key(const std::string_view &key) const noexcept;
/**
* Get the value associated with the given key in a case-insensitive manner.
*
* Note: The key will be matched against **unescaped** JSON.
*
* @return The value associated with this field, or:
* - NO_SUCH_FIELD if the field does not exist in the object
*/
inline simdjson_result<element> at_key_case_insensitive(const std::string_view &key) const noexcept;
/** @private for debugging. Prints out the root element. */
inline bool dump_raw_tape(std::ostream &out) const noexcept;
private:
really_inline element(const document *doc, size_t json_index) noexcept;
friend class document;
friend class object;
friend class array;
friend struct simdjson_result<element>;
template<typename T>
friend class simdjson::minify;
};
/**
* Key/value pair in an object.
*/
@@ -1445,6 +1461,9 @@ public:
inline operator double() const noexcept(false);
inline operator dom::array() const noexcept(false);
inline operator dom::object() const noexcept(false);
inline dom::array::iterator begin() const noexcept(false);
inline dom::array::iterator end() const noexcept(false);
#endif // SIMDJSON_EXCEPTIONS
};
+16
View File
@@ -90,6 +90,15 @@ inline simdjson_result<dom::element>::operator dom::object() const noexcept(fals
return get<dom::object>();
}
inline dom::array::iterator simdjson_result<dom::element>::begin() const noexcept(false) {
if (error()) { throw simdjson_error(error()); }
return first.begin();
}
inline dom::array::iterator simdjson_result<dom::element>::end() const noexcept(false) {
if (error()) { throw simdjson_error(error()); }
return first.end();
}
#endif
//
@@ -830,6 +839,13 @@ inline element::operator double() const noexcept(false) { return get<double>();
inline element::operator array() const noexcept(false) { return get<array>(); }
inline element::operator object() const noexcept(false) { return get<object>(); }
inline dom::array::iterator dom::element::begin() const noexcept(false) {
return get<array>().begin();
}
inline dom::array::iterator dom::element::end() const noexcept(false) {
return get<array>().end();
}
#endif
inline simdjson_result<element> element::operator[](const std::string_view &key) const noexcept {
@@ -211,7 +211,11 @@ bool ParsedJson::Iterator::next() {
ParsedJson::Iterator::Iterator(const ParsedJson &pj) noexcept(false)
: doc(pj.doc), depth(0), location(0), tape_length(0) {
#if SIMDJSON_EXCEPTIONS
if (!pj.valid) { throw simdjson_error(pj.error); }
#else
if (!pj.valid) { abort(); }
#endif
max_depth = pj.max_depth();
depth_index = new scopeindex_t[max_depth + 1];
+59 -101
View File
@@ -1,123 +1,81 @@
#include <iostream>
#include "simdjson.h"
namespace compile_tests {
using namespace std;
using namespace simdjson;
using error_code=simdjson::error_code;
void parser_parse_error_code() {
cout << __func__ << endl;
void basics_1() {
const char *filename = "x.txt";
// Allocate a parser big enough for all files
dom::parser parser;
dom::element doc = parser.load(filename); // load and parse a file
// Read files with the parser, one by one
for (padded_string json : { string("[1, 2, 3]"), string("true"), string("[ true, false ]") }) {
cout << "Parsing " << json.data() << " ..." << endl;
auto [doc, error] = parser.parse(json);
if (error) { cerr << "Error: " << error << endl; exit(1); }
cout << doc << endl;
cout << doc;
}
void basics_2() {
dom::parser parser;
dom::element doc = parser.parse("[1,2,3]"_padded); // parse a string
cout << doc;
}
void basics_dom_1() {
auto 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 = parser.parse(cars_json).get<dom::array>();
// Iterating through an array of objects
for (dom::object car : cars) {
// Accessing a field by name
cout << "Make/Model: " << car["make"] << "/" << car["model"] << endl;
// Casting a JSON element to an integer
uint64_t year = car["year"];
cout << "- This car is " << 2020 - year << "years old." << endl;
// Iterating through an array of floats
double total_tire_pressure = 0;
for (double tire_pressure : car["tire_pressure"]) {
total_tire_pressure += tire_pressure;
}
cout << "- Average tire pressure: " << (total_tire_pressure / 4) << endl;
// Writing out all the information about the car
for (auto [key, value] : car) {
cout << "- " << key << ": " << value << endl;
}
}
}
void parser_parse_many_error_code() {
cout << __func__ << endl;
// Read files with the parser
auto json = "[1, 2, 3] true [ true, false ]"_padded;
cout << "Parsing " << json.data() << " ..." << endl;
void basics_dom_2() {
auto 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;
for (auto [doc, error] : parser.parse_many(json)) {
if (error) { cerr << "Error: " << error << endl; exit(1); }
cout << doc << endl;
}
dom::element cars = parser.parse(cars_json);
cout << cars.at("0/tire_pressure/1") << endl; // Prints 39.9}
}
void parser_parse_max_capacity() {
cout << __func__ << endl;
int argc = 2;
padded_string argv[] { string("[1,2,3]"), string("true") };
dom::parser parser(1024*1024); // Set max capacity to 1MB
for (int i=0;i<argc;i++) {
auto [doc, error] = parser.parse(argv[i]);
if (error == CAPACITY) { cerr << "JSON files larger than 1MB are not supported!" << endl; exit(1); }
if (error) { cerr << error << endl; exit(1); }
cout << doc << endl;
}
}
void parser_parse_fixed_capacity() {
cout << __func__ << endl;
int argc = 2;
padded_string argv[] { string("[1,2,3]"), string("true") };
dom::parser parser(0); // This parser is not allowed to auto-allocate
auto alloc_error = parser.set_capacity(1024*1024);
if (alloc_error) { cerr << alloc_error << endl; exit(1); }; // Set initial capacity to 1MB
for (int i=0;i<argc;i++) {
auto [doc, error] = parser.parse(argv[i]);
if (error == CAPACITY) { cerr << "JSON files larger than 1MB are not supported!" << endl; exit(1); }
if (error) { cerr << error << endl; exit(1); }
cout << doc << endl;
}
}
#if SIMDJSON_EXCEPTIONS
void parser_parse_padded_string() {
cout << __func__ << endl;
auto json = "[ 1, 2, 3 ]"_padded;
void basics_ndjson() {
dom::parser parser;
cout << parser.parse(json) << endl;
}
void parser_parse_get_corpus() {
cout << __func__ << endl;
auto json = get_corpus("jsonexamples/small/demo.json");
dom::parser parser;
cout << parser.parse(json) << endl;
}
void parser_parse_exception() {
cout << __func__ << endl;
// Allocate a parser big enough for all files
dom::parser parser;
// Read files with the parser, one by one
for (padded_string json : { string("[1, 2, 3]"), string("true"), string("[ true, false ]") }) {
cout << "Parsing " << json.data() << " ..." << endl;
cout << parser.parse(json) << endl;
for (dom::element doc : parser.load_many("x.txt")) {
cout << doc["foo"] << endl;
}
// Prints 1 2 3
}
void parser_parse_many_exception() {
cout << __func__ << endl;
// Read files with the parser
auto json = "[1, 2, 3] true [ true, false ]"_padded;
cout << "Parsing " << json.data() << " ..." << endl;
dom::parser parser;
for (const dom::element doc : parser.parse_many(json)) {
cout << doc << endl;
}
}
#endif // SIMDJSON_EXCEPTIONS
} // namespace basics
int main() {
cout << "Running examples." << endl;
parser_parse_error_code();
parser_parse_many_error_code();
parser_parse_max_capacity();
parser_parse_fixed_capacity();
#if SIMDJSON_EXCEPTIONS
parser_parse_exception();
parser_parse_many_exception();
parser_parse_padded_string();
parser_parse_get_corpus();
#endif // SIMDJSON_EXCEPTIONS
cout << "Ran to completion!" << endl;
return 0;
}
+77
View File
@@ -0,0 +1,77 @@
#include <iostream>
#include "simdjson.h"
using namespace std;
using namespace simdjson;
void basics_error_1() {
dom::parser parser;
auto json = "1"_padded;
auto [doc, error] = parser.parse(json); // doc is a dom::element
if (error) { cerr << error << endl; exit(1); }
// Use document here now that we've checked for the error
}
void basics_error_2() {
dom::parser parser;
auto json = "1"_padded;
dom::element doc;
simdjson::error_code error;
parser.parse(json).tie(doc, error); // <-- Assigns to doc and error just like "auto [doc, error]"}
}
void basics_error_3() {
auto 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;
auto [cars, error] = parser.parse(cars_json).get<dom::array>();
if (error) { cerr << error << endl; exit(1); }
// Iterating through an array of objects
for (dom::element car_element : cars) {
dom::object car;
car_element.get<dom::object>().tie(car, error);
if (error) { cerr << error << endl; exit(1); }
// Accessing a field by name
dom::element make, model;
car["make"].tie(make, error);
if (error) { cerr << error << endl; exit(1); }
car["model"].tie(model, error);
if (error) { cerr << error << endl; exit(1); }
cout << "Make/Model: " << make << "/" << model << endl;
// Casting a JSON element to an integer
uint64_t year;
car["year"].get<uint64_t>().tie(year, error);
if (error) { cerr << error << endl; exit(1); }
cout << "- This car is " << 2020 - year << "years old." << endl;
// Iterating through an array of floats
double total_tire_pressure = 0;
dom::array tire_pressure_array;
car["tire_pressure"].get<dom::array>().tie(tire_pressure_array, error);
if (error) { cerr << error << endl; exit(1); }
for (dom::element tire_pressure_element : tire_pressure_array) {
double tire_pressure;
tire_pressure_element.get<double>().tie(tire_pressure, error);
if (error) { cerr << error << endl; exit(1); }
total_tire_pressure += tire_pressure;
}
cout << "- Average tire pressure: " << (total_tire_pressure / 4) << endl;
// Writing out all the information about the car
for (auto [key, value] : car) {
cout << "- " << key << ": " << value << endl;
}
}
}
int main() {
return 0;
}