Move document/element/etc. under dom
This commit is contained in:
parent
de001da35b
commit
03746b966b
|
@ -48,8 +48,8 @@ The simdjson library is easily consumable with a single .h and .cpp file.
|
|||
```c++
|
||||
#include "simdjson.h"
|
||||
int main(void) {
|
||||
simdjson::document::parser parser;
|
||||
simdjson::document::element tweets = parser.load("twitter.json");
|
||||
simdjson::dom::parser parser;
|
||||
simdjson::dom::element tweets = parser.load("twitter.json");
|
||||
std::cout << tweets["search_metadata"]["count"] << " results." << std::endl;
|
||||
}
|
||||
```
|
||||
|
|
|
@ -127,7 +127,7 @@ int main(int argc, char *argv[]) {
|
|||
std::cerr << "Please specify at least one file name. " << std::endl;
|
||||
}
|
||||
const char * filename = argv[1];
|
||||
simdjson::document::parser parser;
|
||||
simdjson::dom::parser parser;
|
||||
auto [doc, error] = parser.load(filename); // do the parsing
|
||||
if (error) {
|
||||
std::cout << "parse failed" << std::endl;
|
||||
|
|
|
@ -16,8 +16,8 @@ const padded_string EMPTY_ARRAY("[]", 2);
|
|||
|
||||
static void twitter_count(State& state) {
|
||||
// Prints the number of results in twitter.json
|
||||
document::parser parser;
|
||||
document::element doc = parser.load(JSON_TEST_PATH);
|
||||
dom::parser parser;
|
||||
dom::element doc = parser.load(JSON_TEST_PATH);
|
||||
for (auto _ : state) {
|
||||
uint64_t result_count = doc["search_metadata"]["count"];
|
||||
if (result_count != 100) { return; }
|
||||
|
@ -44,12 +44,12 @@ BENCHMARK(iterator_twitter_count);
|
|||
|
||||
static void twitter_default_profile(State& state) {
|
||||
// Count unique users with a default profile.
|
||||
document::parser parser;
|
||||
document::element doc = parser.load(JSON_TEST_PATH);
|
||||
dom::parser parser;
|
||||
dom::element doc = parser.load(JSON_TEST_PATH);
|
||||
for (auto _ : state) {
|
||||
set<string_view> default_users;
|
||||
for (document::object tweet : doc["statuses"].as_array()) {
|
||||
document::object user = tweet["user"];
|
||||
for (dom::object tweet : doc["statuses"].as_array()) {
|
||||
dom::object user = tweet["user"];
|
||||
if (user["default_profile"]) {
|
||||
default_users.insert(user["screen_name"]);
|
||||
}
|
||||
|
@ -61,14 +61,14 @@ BENCHMARK(twitter_default_profile);
|
|||
|
||||
static void twitter_image_sizes(State& state) {
|
||||
// Count unique image sizes
|
||||
document::parser parser;
|
||||
document::element doc = parser.load(JSON_TEST_PATH);
|
||||
dom::parser parser;
|
||||
dom::element doc = parser.load(JSON_TEST_PATH);
|
||||
for (auto _ : state) {
|
||||
set<tuple<uint64_t, uint64_t>> image_sizes;
|
||||
for (document::object tweet : doc["statuses"].as_array()) {
|
||||
for (dom::object tweet : doc["statuses"].as_array()) {
|
||||
auto [media, not_found] = tweet["entities"]["media"];
|
||||
if (!not_found) {
|
||||
for (document::object image : media.as_array()) {
|
||||
for (dom::object image : media.as_array()) {
|
||||
for (auto [key, size] : image["sizes"].as_object()) {
|
||||
image_sizes.insert({ size["w"], size["h"] });
|
||||
}
|
||||
|
@ -84,8 +84,8 @@ BENCHMARK(twitter_image_sizes);
|
|||
|
||||
static void error_code_twitter_count(State& state) noexcept {
|
||||
// Prints the number of results in twitter.json
|
||||
document::parser parser;
|
||||
document::element doc = parser.load(JSON_TEST_PATH);
|
||||
dom::parser parser;
|
||||
dom::element doc = parser.load(JSON_TEST_PATH);
|
||||
for (auto _ : state) {
|
||||
auto [value, error] = doc["search_metadata"]["count"].as_uint64_t();
|
||||
if (error) { return; }
|
||||
|
@ -96,14 +96,14 @@ BENCHMARK(error_code_twitter_count);
|
|||
|
||||
static void error_code_twitter_default_profile(State& state) noexcept {
|
||||
// Count unique users with a default profile.
|
||||
document::parser parser;
|
||||
document::element doc = parser.load(JSON_TEST_PATH);
|
||||
dom::parser parser;
|
||||
dom::element doc = parser.load(JSON_TEST_PATH);
|
||||
for (auto _ : state) {
|
||||
set<string_view> default_users;
|
||||
|
||||
auto [tweets, error] = doc["statuses"].as_array();
|
||||
if (error) { return; }
|
||||
for (document::element tweet : tweets) {
|
||||
for (dom::element tweet : tweets) {
|
||||
auto [user, error2] = tweet["user"].as_object();
|
||||
if (error2) { return; }
|
||||
auto [default_profile, error3] = user["default_profile"].as_bool();
|
||||
|
@ -128,12 +128,12 @@ static void iterator_twitter_default_profile(State& state) {
|
|||
set<string_view> default_users;
|
||||
ParsedJson::Iterator iter(pj);
|
||||
|
||||
// for (document::object tweet : doc["statuses"].as_array()) {
|
||||
// for (dom::object tweet : doc["statuses"].as_array()) {
|
||||
if (!(iter.move_to_key("statuses") && iter.is_array())) { return; }
|
||||
if (iter.down()) { // first status
|
||||
do {
|
||||
|
||||
// document::object user = tweet["user"];
|
||||
// dom::object user = tweet["user"];
|
||||
if (!(iter.move_to_key("user") && iter.is_object())) { return; }
|
||||
|
||||
// if (user["default_profile"]) {
|
||||
|
@ -160,16 +160,16 @@ BENCHMARK(iterator_twitter_default_profile);
|
|||
|
||||
static void error_code_twitter_image_sizes(State& state) noexcept {
|
||||
// Count unique image sizes
|
||||
document::parser parser;
|
||||
document::element doc = parser.load(JSON_TEST_PATH);
|
||||
dom::parser parser;
|
||||
dom::element doc = parser.load(JSON_TEST_PATH);
|
||||
for (auto _ : state) {
|
||||
set<tuple<uint64_t, uint64_t>> image_sizes;
|
||||
auto [statuses, error] = doc["statuses"].as_array();
|
||||
if (error) { return; }
|
||||
for (document::element tweet : statuses) {
|
||||
for (dom::element tweet : statuses) {
|
||||
auto [images, not_found] = tweet["entities"]["media"].as_array();
|
||||
if (!not_found) {
|
||||
for (document::element image : images) {
|
||||
for (dom::element image : images) {
|
||||
auto [sizes, error2] = image["sizes"].as_object();
|
||||
if (error2) { return; }
|
||||
for (auto [key, size] : sizes) {
|
||||
|
@ -194,7 +194,7 @@ static void iterator_twitter_image_sizes(State& state) {
|
|||
set<tuple<uint64_t, uint64_t>> image_sizes;
|
||||
ParsedJson::Iterator iter(pj);
|
||||
|
||||
// for (document::object tweet : doc["statuses"].as_array()) {
|
||||
// for (dom::object tweet : doc["statuses"].as_array()) {
|
||||
if (!(iter.move_to_key("statuses") && iter.is_array())) { return; }
|
||||
if (iter.down()) { // first status
|
||||
do {
|
||||
|
@ -206,7 +206,7 @@ static void iterator_twitter_image_sizes(State& state) {
|
|||
if (iter.move_to_key("media")) {
|
||||
if (!iter.is_array()) { return; }
|
||||
|
||||
// for (document::object image : media.as_array()) {
|
||||
// for (dom::object image : media.as_array()) {
|
||||
if (iter.down()) { // first media
|
||||
do {
|
||||
|
||||
|
@ -247,7 +247,7 @@ BENCHMARK(iterator_twitter_image_sizes);
|
|||
static void print_json(State& state) noexcept {
|
||||
// Prints the number of results in twitter.json
|
||||
padded_string json = get_corpus(JSON_TEST_PATH);
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
if (!parser.allocate_capacity(json.length())) { cerr << "allocation failed" << endl; return; }
|
||||
if (int error = json_parse(json, parser); error != SUCCESS) { cerr << error_message(error) << endl; return; }
|
||||
for (auto _ : state) {
|
||||
|
|
|
@ -7,7 +7,7 @@ using namespace std;
|
|||
const padded_string EMPTY_ARRAY("[]", 2);
|
||||
|
||||
static void json_parse(State& state) {
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
if (parser.set_capacity(EMPTY_ARRAY.length())) { return; }
|
||||
for (auto _ : state) {
|
||||
auto error = simdjson::json_parse(EMPTY_ARRAY, parser);
|
||||
|
@ -16,7 +16,7 @@ static void json_parse(State& state) {
|
|||
}
|
||||
BENCHMARK(json_parse);
|
||||
static void parser_parse_error_code(State& state) {
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
if (parser.set_capacity(EMPTY_ARRAY.length())) { return; }
|
||||
for (auto _ : state) {
|
||||
auto [doc, error] = parser.parse(EMPTY_ARRAY);
|
||||
|
@ -25,11 +25,11 @@ static void parser_parse_error_code(State& state) {
|
|||
}
|
||||
BENCHMARK(parser_parse_error_code);
|
||||
static void parser_parse_exception(State& state) {
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
if (parser.set_capacity(EMPTY_ARRAY.length())) { return; }
|
||||
for (auto _ : state) {
|
||||
try {
|
||||
UNUSED document::element doc = parser.parse(EMPTY_ARRAY);
|
||||
UNUSED dom::element doc = parser.parse(EMPTY_ARRAY);
|
||||
} catch(simdjson_error &j) {
|
||||
return;
|
||||
}
|
||||
|
@ -39,14 +39,14 @@ BENCHMARK(parser_parse_exception);
|
|||
|
||||
static void build_parsed_json(State& state) {
|
||||
for (auto _ : state) {
|
||||
document::parser parser = simdjson::build_parsed_json(EMPTY_ARRAY);
|
||||
dom::parser parser = simdjson::build_parsed_json(EMPTY_ARRAY);
|
||||
if (!parser.valid) { return; }
|
||||
}
|
||||
}
|
||||
BENCHMARK(build_parsed_json);
|
||||
static void document_parse_error_code(State& state) {
|
||||
for (auto _ : state) {
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
auto [doc, error] = parser.parse(EMPTY_ARRAY);
|
||||
if (error) { return; }
|
||||
}
|
||||
|
@ -55,8 +55,8 @@ BENCHMARK(document_parse_error_code);
|
|||
static void document_parse_exception(State& state) {
|
||||
for (auto _ : state) {
|
||||
try {
|
||||
document::parser parser;
|
||||
UNUSED document::element doc = parser.parse(EMPTY_ARRAY);
|
||||
dom::parser parser;
|
||||
UNUSED dom::element doc = parser.parse(EMPTY_ARRAY);
|
||||
} catch(simdjson_error &j) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -125,7 +125,7 @@ struct option_struct {
|
|||
if (arch == architecture::UNSUPPORTED) {
|
||||
arch = find_best_supported_architecture();
|
||||
}
|
||||
document::parser::use_implementation(arch);
|
||||
dom::parser::use_implementation(arch);
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
|
|
|
@ -77,7 +77,7 @@ struct json_stats {
|
|||
size_t blocks_with_16_structurals = 0;
|
||||
size_t blocks_with_16_structurals_flipped = 0;
|
||||
|
||||
json_stats(const padded_string& json, const document::parser& parser) {
|
||||
json_stats(const padded_string& json, const dom::parser& parser) {
|
||||
bytes = json.size();
|
||||
blocks = bytes / BYTES_PER_BLOCK;
|
||||
if (bytes % BYTES_PER_BLOCK > 0) { blocks++; } // Account for remainder block
|
||||
|
@ -291,9 +291,9 @@ struct benchmarker {
|
|||
}
|
||||
|
||||
really_inline void run_iteration(bool stage1_only, bool hotbuffers=false) {
|
||||
// Allocate document::parser
|
||||
// Allocate dom::parser
|
||||
collector.start();
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
bool alloc_ok = parser.allocate_capacity(json.size());
|
||||
event_count allocate_count = collector.end();
|
||||
allocate_stage << allocate_count;
|
||||
|
|
|
@ -38,7 +38,7 @@ void print_vec(const std::vector<int64_t> &v) {
|
|||
// clang-format off
|
||||
|
||||
// simdjson_recurse below come be implemented like so but it is slow:
|
||||
/*void simdjson_recurse(std::vector<int64_t> & v, simdjson::document::element element) {
|
||||
/*void simdjson_recurse(std::vector<int64_t> & v, simdjson::dom::element element) {
|
||||
if (element.is_array()) {
|
||||
auto [array, array_error] = element.as_array();
|
||||
for (auto child : array) {
|
||||
|
@ -63,7 +63,7 @@ void print_vec(const std::vector<int64_t> &v) {
|
|||
// clang-format on
|
||||
|
||||
|
||||
void simdjson_recurse(std::vector<int64_t> & v, simdjson::document::element element) {
|
||||
void simdjson_recurse(std::vector<int64_t> & v, simdjson::dom::element element) {
|
||||
if (element.is_array()) {
|
||||
auto array = element.as_array();
|
||||
for (auto child : array) {
|
||||
|
@ -100,7 +100,7 @@ void simdjson_recurse(std::vector<int64_t> & v, simdjson::document::element elem
|
|||
}
|
||||
|
||||
__attribute__((noinline)) std::vector<int64_t>
|
||||
simdjson_just_dom(simdjson::document::element doc) {
|
||||
simdjson_just_dom(simdjson::dom::element doc) {
|
||||
std::vector<int64_t> answer;
|
||||
simdjson_recurse(answer, doc);
|
||||
remove_duplicates(answer);
|
||||
|
@ -110,8 +110,8 @@ simdjson_just_dom(simdjson::document::element doc) {
|
|||
__attribute__((noinline)) std::vector<int64_t>
|
||||
simdjson_compute_stats(const simdjson::padded_string &p) {
|
||||
std::vector<int64_t> answer;
|
||||
simdjson::document::parser parser;
|
||||
simdjson::document::element doc = parser.parse(p);
|
||||
simdjson::dom::parser parser;
|
||||
simdjson::dom::element doc = parser.parse(p);
|
||||
simdjson_recurse(answer, doc);
|
||||
remove_duplicates(answer);
|
||||
return answer;
|
||||
|
@ -119,7 +119,7 @@ simdjson_compute_stats(const simdjson::padded_string &p) {
|
|||
|
||||
__attribute__((noinline)) simdjson::error_code
|
||||
simdjson_just_parse(const simdjson::padded_string &p) {
|
||||
simdjson::document::parser parser;
|
||||
simdjson::dom::parser parser;
|
||||
return parser.parse(p).error();
|
||||
}
|
||||
|
||||
|
@ -372,8 +372,8 @@ int main(int argc, char *argv[]) {
|
|||
volume, !just_data);
|
||||
BEST_TIME("sasjon (just parse) ", sasjon_just_parse(p), false, , repeat,
|
||||
volume, !just_data);
|
||||
simdjson::document::parser parser;
|
||||
simdjson::document::element doc = parser.parse(p);
|
||||
simdjson::dom::parser parser;
|
||||
simdjson::dom::element doc = parser.parse(p);
|
||||
BEST_TIME("simdjson (just dom) ", simdjson_just_dom(doc).size(), size,
|
||||
, repeat, volume, !just_data);
|
||||
char *buffer = (char *)malloc(p.size() + 1);
|
||||
|
|
|
@ -151,7 +151,7 @@ int main(int argc, char *argv[]) {
|
|||
.is_valid(),
|
||||
true, memcpy(buffer, mini_buffer, p.size()), repeat, volume, !just_data);
|
||||
|
||||
simdjson::document::parser parser;
|
||||
simdjson::dom::parser parser;
|
||||
bool automated_reallocation = false;
|
||||
BEST_TIME("simdjson orig",
|
||||
parser.parse((const uint8_t *)buffer, p.size(),
|
||||
|
|
|
@ -35,7 +35,7 @@ int main (int argc, char *argv[]){
|
|||
std::cout << "Gigabytes/second\t" << "Nb of documents parsed" << std::endl;
|
||||
for (auto i = 0; i < 3; i++) {
|
||||
//Actual test
|
||||
simdjson::document::parser parser;
|
||||
simdjson::dom::parser parser;
|
||||
simdjson::error_code alloc_error = parser.set_capacity(p.size());
|
||||
if (alloc_error) {
|
||||
std::cerr << alloc_error << std::endl;
|
||||
|
@ -76,7 +76,7 @@ int main (int argc, char *argv[]){
|
|||
int count;
|
||||
for (size_t j = 0; j < 5; j++) {
|
||||
//Actual test
|
||||
simdjson::document::parser parser;
|
||||
simdjson::dom::parser parser;
|
||||
simdjson::error_code error;
|
||||
|
||||
auto start = std::chrono::steady_clock::now();
|
||||
|
@ -115,7 +115,7 @@ int main (int argc, char *argv[]){
|
|||
for (int i = 0; i < NB_ITERATION; i++) {
|
||||
|
||||
// Actual test
|
||||
simdjson::document::parser parser;
|
||||
simdjson::dom::parser parser;
|
||||
simdjson::error_code error;
|
||||
|
||||
auto start = std::chrono::steady_clock::now();
|
||||
|
|
|
@ -50,7 +50,7 @@ void print_stat(const stat_t &s) {
|
|||
|
||||
|
||||
really_inline void simdjson_process_atom(stat_t &s,
|
||||
simdjson::document::element element) {
|
||||
simdjson::dom::element element) {
|
||||
if (element.is_number()) {
|
||||
s.number_count++;
|
||||
} else if (element.is_bool()) {
|
||||
|
@ -64,7 +64,7 @@ really_inline void simdjson_process_atom(stat_t &s,
|
|||
}
|
||||
}
|
||||
|
||||
void simdjson_recurse(stat_t &s, simdjson::document::element element) {
|
||||
void simdjson_recurse(stat_t &s, simdjson::dom::element element) {
|
||||
if (element.is_array()) {
|
||||
s.array_count++;
|
||||
auto [array, array_error] = element.as_array();
|
||||
|
@ -93,7 +93,7 @@ void simdjson_recurse(stat_t &s, simdjson::document::element element) {
|
|||
__attribute__((noinline)) stat_t
|
||||
simdjson_compute_stats(const simdjson::padded_string &p) {
|
||||
stat_t s{};
|
||||
simdjson::document::parser parser;
|
||||
simdjson::dom::parser parser;
|
||||
auto [doc, error] = parser.parse(p);
|
||||
if (error) {
|
||||
s.valid = false;
|
||||
|
|
|
@ -109,10 +109,10 @@ bool bench(const char *filename, bool verbose, bool just_data, int repeat_multip
|
|||
}
|
||||
|
||||
if (!just_data)
|
||||
BEST_TIME("simdjson (dynamic mem) ", !simdjson::document::parser().parse(p).error(), true,
|
||||
BEST_TIME("simdjson (dynamic mem) ", !simdjson::dom::parser().parse(p).error(), true,
|
||||
, repeat, volume, !just_data);
|
||||
// (static alloc)
|
||||
simdjson::document::parser parser;
|
||||
simdjson::dom::parser parser;
|
||||
BEST_TIME("simdjson ", parser.parse(p).error(), simdjson::SUCCESS, , repeat, volume,
|
||||
!just_data);
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ using stat_t = struct stat_s;
|
|||
|
||||
|
||||
really_inline void simdjson_process_atom(stat_t &s,
|
||||
simdjson::document::element element) {
|
||||
simdjson::dom::element element) {
|
||||
if (element.is_integer()) {
|
||||
s.integer_count++;
|
||||
} else if(element.is_string()) {
|
||||
|
@ -62,7 +62,7 @@ really_inline void simdjson_process_atom(stat_t &s,
|
|||
}
|
||||
}
|
||||
|
||||
void simdjson_recurse(stat_t &s, simdjson::document::element element) {
|
||||
void simdjson_recurse(stat_t &s, simdjson::dom::element element) {
|
||||
if (element.is_array()) {
|
||||
s.array_count++;
|
||||
auto [array, array_error] = element.as_array();
|
||||
|
@ -91,7 +91,7 @@ void simdjson_recurse(stat_t &s, simdjson::document::element element) {
|
|||
|
||||
stat_t simdjson_compute_stats(const simdjson::padded_string &p) {
|
||||
stat_t answer{};
|
||||
simdjson::document::parser parser;
|
||||
simdjson::dom::parser parser;
|
||||
auto [doc, error] = parser.parse(p);
|
||||
if (error) {
|
||||
answer.valid = false;
|
||||
|
@ -159,7 +159,7 @@ int main(int argc, char *argv[]) {
|
|||
s.non_ascii_byte_count, s.object_count, s.array_count, s.null_count,
|
||||
s.true_count, s.false_count, s.byte_count, s.structural_indexes_count);
|
||||
#ifdef __linux__
|
||||
simdjson::document::parser parser;
|
||||
simdjson::dom::parser parser;
|
||||
const simdjson::implementation &stage_parser = *simdjson::active_implementation;
|
||||
bool allocok = parser.allocate_capacity(p.size());
|
||||
if (!allocok) {
|
||||
|
|
|
@ -34,19 +34,19 @@ The Basics: Loading and Parsing JSON Documents
|
|||
----------------------------------------------
|
||||
|
||||
The simdjson library offers a simple DOM tree API, which you can access by creating a
|
||||
`document::parser` and calling the `load()` method:
|
||||
`dom::parser` and calling the `load()` method:
|
||||
|
||||
```c++
|
||||
document::parser parser;
|
||||
document::element doc = parser.load(filename); // load and parse a file
|
||||
dom::parser parser;
|
||||
dom::element doc = parser.load(filename); // load and parse a file
|
||||
```
|
||||
|
||||
Or by creating a padded string (for efficiency reasons, simdjson requires a string with
|
||||
SIMDJSON_PADDING bytes at the end) and calling `parse()`:
|
||||
|
||||
```c++
|
||||
document::parser parser;
|
||||
document::element doc = parser.parse("[1,2,3]"_padded); // parse a string
|
||||
dom::parser parser;
|
||||
dom::element doc = parser.parse("[1,2,3]"_padded); // parse a string
|
||||
```
|
||||
|
||||
Using the Parsed JSON
|
||||
|
@ -56,7 +56,7 @@ Once you have an element, you can navigate it with idiomatic C++ iterators, oper
|
|||
|
||||
* **Extracting Values:** You can cast a JSON element to a native type: `double(element)` or
|
||||
`double x = json_element`. This works for double, uint64_t, int64_t, bool,
|
||||
document::object and document::array. You can also use is_*typename*()` to test if it is a
|
||||
dom::object and dom::array. You can also use is_*typename*()` to test if it is a
|
||||
given type, and as_*typename*() to do the cast and return an error code on failure instead of an
|
||||
exception.
|
||||
* **Field Access:** To get the value of the "foo" field in an object, use `object["foo"]`.
|
||||
|
@ -72,11 +72,11 @@ auto cars_json = R"( [
|
|||
{ "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;
|
||||
document::parser parser;
|
||||
document::array cars = parser.parse(cars_json).as_array();
|
||||
dom::parser parser;
|
||||
dom::array cars = parser.parse(cars_json).as_array();
|
||||
|
||||
// Iterating through an array of objects
|
||||
for (document::object car : cars) {
|
||||
for (dom::object car : cars) {
|
||||
// Accessing a field by name
|
||||
cout << "Make/Model: " << car["make"] << "/" << car["model"] << endl;
|
||||
|
||||
|
@ -109,8 +109,8 @@ auto cars_json = R"( [
|
|||
{ "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;
|
||||
document::parser parser;
|
||||
document::element cars = parser.parse(cars_json);
|
||||
dom::parser parser;
|
||||
dom::element cars = parser.parse(cars_json);
|
||||
cout << cars["/0/tire_pressure/1"] << endl; // Prints 39.9
|
||||
```
|
||||
|
||||
|
@ -121,7 +121,7 @@ All simdjson APIs that can fail return `simdjson_result<T>`, which is a <valu
|
|||
pair. The error codes and values can be accessed directly, reading the error like so:
|
||||
|
||||
```c++
|
||||
auto [doc, error] = parser.parse(json); // doc is a document::element
|
||||
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
|
||||
```
|
||||
|
@ -136,7 +136,7 @@ behavior.
|
|||
> circumvent this, you can use this instead:
|
||||
>
|
||||
> ```c++
|
||||
> document::element doc;
|
||||
> dom::element doc;
|
||||
> error_code error;
|
||||
> parser.parse(json).tie(doc, error); // <-- Assigns to doc and error just like "auto [doc, error]"
|
||||
> ```
|
||||
|
@ -151,18 +151,18 @@ auto cars_json = R"( [
|
|||
{ "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;
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
auto [doc, error] = parser.parse(cars_json);
|
||||
if (error) { cerr << error << endl; exit(1); }
|
||||
|
||||
// Iterating through an array of objects
|
||||
for (document::element car_element : cars) {
|
||||
document::object car;
|
||||
for (dom::element car_element : cars) {
|
||||
dom::object car;
|
||||
car_element.as_object().tie(car, error);
|
||||
if (error) { cerr << error << endl; exit(1); }
|
||||
|
||||
// Accessing a field by name
|
||||
document::element make, model;
|
||||
dom::element make, model;
|
||||
car["make"].tie(make, error);
|
||||
if (error) { cerr << error << endl; exit(1); }
|
||||
car["model"].tie(model, error);
|
||||
|
@ -177,7 +177,7 @@ for (document::element car_element : cars) {
|
|||
|
||||
// Iterating through an array of floats
|
||||
double total_tire_pressure = 0;
|
||||
for (document::element tire_pressure_element : car["tire_pressure"]) {
|
||||
for (dom::element tire_pressure_element : car["tire_pressure"]) {
|
||||
double tire_pressure;
|
||||
tire_pressure_element.as_uint64_t().tie(tire_pressure, error);
|
||||
if (error) { cerr << error << endl; exit(1); }
|
||||
|
@ -197,7 +197,7 @@ for (document::element car_element : cars) {
|
|||
Users more comfortable with an exception flow may choose to directly cast the `simdjson_result<T>` to the desired type:
|
||||
|
||||
```c++
|
||||
document::element doc = parser.parse(json); // Throws an exception if there was an error!
|
||||
dom::element doc = parser.parse(json); // Throws an exception if there was an error!
|
||||
```
|
||||
|
||||
When used this way, a `simdjson_error` exception will be thrown if an error occurs, preventing the
|
||||
|
@ -216,8 +216,8 @@ auto ndjson = R"(
|
|||
{ "foo": 2 }
|
||||
{ "foo": 3 }
|
||||
)"_padded;
|
||||
document::parser parser;
|
||||
for (document::element doc : parser.load_many(filename)) {
|
||||
dom::parser parser;
|
||||
for (dom::element doc : parser.load_many(filename)) {
|
||||
cout << doc["foo"] << endl;
|
||||
}
|
||||
// Prints 1 2 3
|
||||
|
@ -229,7 +229,7 @@ Thread Safety
|
|||
-------------
|
||||
|
||||
The simdjson library is mostly single-threaded. Thread safety is the responsibility of the caller:
|
||||
it is unsafe to reuse a document::parser object between different threads.
|
||||
it is unsafe to reuse a dom::parser object between different threads.
|
||||
|
||||
simdjson's CPU detection, which runs the first time parsing is attempted and switches to the fastest
|
||||
parser for your CPU, is transparent and thread-safe.
|
||||
|
|
|
@ -18,10 +18,10 @@ and reuse it. The simdjson library will allocate and retain internal buffers bet
|
|||
buffers hot in cache and keeping memory allocation and initialization to a minimum.
|
||||
|
||||
```c++
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
|
||||
// This initializes buffers and a document big enough to handle this JSON.
|
||||
document::element doc = parser.parse("[ true, false ]"_padded);
|
||||
dom::element doc = parser.parse("[ true, false ]"_padded);
|
||||
cout << doc << endl;
|
||||
|
||||
// This reuses the existing buffers, and reuses and *overwrites* the old document
|
||||
|
@ -29,20 +29,20 @@ doc = parser.parse("[1, 2, 3]"_padded);
|
|||
cout << doc << endl;
|
||||
|
||||
// This also reuses the existing buffers, and reuses and *overwrites* the old document
|
||||
document::element doc2 = parser.parse("true"_padded);
|
||||
dom::element doc2 = parser.parse("true"_padded);
|
||||
// Even if you keep the old reference around, doc and doc2 refer to the same document.
|
||||
cout << doc << endl;
|
||||
cout << doc2 << endl;
|
||||
```
|
||||
|
||||
It's not just internal buffers though. The simdjson library reuses the document itself. document::element, document::object and document::array are *references* to the internal document.
|
||||
It's not just internal buffers though. The simdjson library reuses the document itself. dom::element, dom::object and dom::array are *references* to the internal document.
|
||||
You are only *borrowing* the document from simdjson, which purposely reuses and overwrites it each
|
||||
time you call parse. This prevent wasteful and unnecessary memory allocation in 99% of cases where
|
||||
JSON is just read, used, and converted to native values or thrown away.
|
||||
|
||||
> **You are only borrowing the document from the simdjson parser. Don't keep it long term!**
|
||||
|
||||
This is key: don't keep the `document&`, `document::element`, `document::array`, `document::object`
|
||||
This is key: don't keep the `document&`, `dom::element`, `dom::array`, `dom::object`
|
||||
or `string_view` objects you get back from the API. Convert them to C++ native values, structs and
|
||||
arrays that you own.
|
||||
|
||||
|
@ -61,7 +61,7 @@ without bound:
|
|||
* You can set a *max capacity* when constructing a parser:
|
||||
|
||||
```c++
|
||||
document::parser parser(1024*1024); // Never grow past documents > 1MB
|
||||
dom::parser parser(1024*1024); // Never grow past documents > 1MB
|
||||
for (web_request request : listen()) {
|
||||
auto [doc, error] = parser.parse(request.body);
|
||||
// If the document was above our limit, emit 413 = payload too large
|
||||
|
@ -76,7 +76,7 @@ without bound:
|
|||
predictability and reliability, since simdjson will never call malloc after startup!
|
||||
|
||||
```c++
|
||||
document::parser parser(0); // This parser will refuse to automatically grow capacity
|
||||
dom::parser parser(0); // This parser will refuse to automatically grow capacity
|
||||
parser.set_capacity(1024*1024); // This allocates enough capacity to handle documents <= 1MB
|
||||
for (web_request request : listen()) {
|
||||
auto [doc, error] = parser.parse(request.body);
|
||||
|
|
|
@ -30,7 +30,7 @@ constexpr size_t SIMDJSON_PADDING = 32;
|
|||
/**
|
||||
* By default, simdjson supports this many nested objects and arrays.
|
||||
*
|
||||
* This is the default for document::parser::max_depth().
|
||||
* This is the default for parser::max_depth().
|
||||
*/
|
||||
constexpr size_t DEFAULT_MAX_DEPTH = 1024;
|
||||
|
||||
|
|
|
@ -10,13 +10,80 @@
|
|||
#include "simdjson/simdjson.h"
|
||||
#include "simdjson/padded_string.h"
|
||||
|
||||
namespace simdjson::dom {
|
||||
|
||||
class parser;
|
||||
class element;
|
||||
class array;
|
||||
class object;
|
||||
class key_value_pair;
|
||||
class stream;
|
||||
class document;
|
||||
|
||||
/** The default batch size for parser.parse_many() and parser.load_many() */
|
||||
static constexpr size_t DEFAULT_BATCH_SIZE = 1000000;
|
||||
|
||||
} // namespace simdjson::dom
|
||||
|
||||
namespace simdjson {
|
||||
|
||||
template<> struct simdjson_result<dom::element>;
|
||||
template<> struct simdjson_result<dom::array>;
|
||||
template<> struct simdjson_result<dom::object>;
|
||||
|
||||
template<typename T>
|
||||
class minify;
|
||||
|
||||
} // namespace simdjson
|
||||
|
||||
namespace simdjson::internal {
|
||||
|
||||
using namespace simdjson::dom;
|
||||
|
||||
constexpr const uint64_t JSON_VALUE_MASK = 0x00FFFFFFFFFFFFFF;
|
||||
enum class tape_type;
|
||||
class tape_ref;
|
||||
/**
|
||||
* The possible types in the tape. Internal only.
|
||||
*/
|
||||
enum class tape_type {
|
||||
ROOT = 'r',
|
||||
START_ARRAY = '[',
|
||||
START_OBJECT = '{',
|
||||
END_ARRAY = ']',
|
||||
END_OBJECT = '}',
|
||||
STRING = '"',
|
||||
INT64 = 'l',
|
||||
UINT64 = 'u',
|
||||
DOUBLE = 'd',
|
||||
TRUE_VALUE = 't',
|
||||
FALSE_VALUE = 'f',
|
||||
NULL_VALUE = 'n'
|
||||
};
|
||||
|
||||
/**
|
||||
* A reference to an element on the tape. Internal only.
|
||||
*/
|
||||
class tape_ref {
|
||||
public:
|
||||
really_inline tape_ref() noexcept;
|
||||
really_inline tape_ref(const document *doc, size_t json_index) noexcept;
|
||||
inline size_t after_element() const noexcept;
|
||||
really_inline tape_type type() const noexcept;
|
||||
really_inline uint64_t tape_value() const noexcept;
|
||||
template<typename T>
|
||||
really_inline T next_tape_value() const noexcept;
|
||||
inline std::string_view get_string_view() const noexcept;
|
||||
|
||||
/** The document this element references. */
|
||||
const document *doc;
|
||||
|
||||
/** The index of this element on `doc.tape[]` */
|
||||
size_t json_index;
|
||||
};
|
||||
} // namespace simdjson::internal
|
||||
|
||||
namespace simdjson {
|
||||
namespace simdjson::dom {
|
||||
|
||||
/**
|
||||
* A parsed JSON document.
|
||||
|
@ -48,17 +115,6 @@ public:
|
|||
document &operator=(document &&other) noexcept = default;
|
||||
document &operator=(const document &) = delete; // Disallow copying
|
||||
|
||||
/** The default batch size for parse_many and load_many */
|
||||
static constexpr size_t DEFAULT_BATCH_SIZE = 1000000;
|
||||
|
||||
// Nested classes
|
||||
class element;
|
||||
class array;
|
||||
class object;
|
||||
class key_value_pair;
|
||||
class parser;
|
||||
class stream;
|
||||
|
||||
/**
|
||||
* Get the root element of this document as a JSON array.
|
||||
*/
|
||||
|
@ -78,64 +134,17 @@ public:
|
|||
private:
|
||||
inline error_code set_capacity(size_t len) noexcept;
|
||||
template<typename T>
|
||||
friend class minify;
|
||||
friend class simdjson::minify;
|
||||
friend class parser;
|
||||
}; // class document
|
||||
|
||||
template<typename T>
|
||||
class minify;
|
||||
|
||||
namespace internal {
|
||||
/**
|
||||
* The possible types in the tape. Internal only.
|
||||
*/
|
||||
enum class tape_type {
|
||||
ROOT = 'r',
|
||||
START_ARRAY = '[',
|
||||
START_OBJECT = '{',
|
||||
END_ARRAY = ']',
|
||||
END_OBJECT = '}',
|
||||
STRING = '"',
|
||||
INT64 = 'l',
|
||||
UINT64 = 'u',
|
||||
DOUBLE = 'd',
|
||||
TRUE_VALUE = 't',
|
||||
FALSE_VALUE = 'f',
|
||||
NULL_VALUE = 'n'
|
||||
};
|
||||
|
||||
/**
|
||||
* A reference to an element on the tape. Internal only.
|
||||
*/
|
||||
class tape_ref {
|
||||
protected:
|
||||
really_inline tape_ref() noexcept;
|
||||
really_inline tape_ref(const document *_doc, size_t _json_index) noexcept;
|
||||
inline size_t after_element() const noexcept;
|
||||
really_inline tape_type type() const noexcept;
|
||||
really_inline uint64_t tape_value() const noexcept;
|
||||
template<typename T>
|
||||
really_inline T next_tape_value() const noexcept;
|
||||
inline std::string_view get_string_view() const noexcept;
|
||||
|
||||
/** The document this element references. */
|
||||
const document *doc;
|
||||
|
||||
/** The index of this element on `doc.tape[]` */
|
||||
size_t json_index;
|
||||
|
||||
friend class document::key_value_pair;
|
||||
template<typename T>
|
||||
friend class simdjson::minify;
|
||||
};
|
||||
} // namespace simdjson::internal
|
||||
|
||||
/**
|
||||
* A JSON element.
|
||||
*
|
||||
* References an element in a JSON document, representing a JSON null, boolean, string, number,
|
||||
* array or object.
|
||||
*/
|
||||
class document::element : protected internal::tape_ref {
|
||||
class element : protected internal::tape_ref {
|
||||
public:
|
||||
/** Create a new, invalid element. */
|
||||
really_inline element() noexcept;
|
||||
|
@ -295,21 +304,21 @@ public:
|
|||
* @return The JSON array.
|
||||
* @exception simdjson_error(UNEXPECTED_TYPE) if the JSON element is not an array
|
||||
*/
|
||||
inline operator document::array() const noexcept(false);
|
||||
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 document::object() const noexcept(false);
|
||||
inline operator object() const noexcept(false);
|
||||
#endif // SIMDJSON_EXCEPTIONS
|
||||
|
||||
/**
|
||||
* Get the value associated with the given JSON pointer.
|
||||
*
|
||||
* document::parser parser;
|
||||
* document::element doc = parser.parse(R"({ "foo": { "a": [ 10, 20, 30 ] }})");
|
||||
* dom::parser parser;
|
||||
* element doc = parser.parse(R"({ "foo": { "a": [ 10, 20, 30 ] }})");
|
||||
* doc["/foo/a/1"] == 20
|
||||
* doc["/"]["foo"]["a"].at(1) == 20
|
||||
* doc[""]["foo"]["a"].at(1) == 20
|
||||
|
@ -325,8 +334,8 @@ public:
|
|||
/**
|
||||
* Get the value associated with the given JSON pointer.
|
||||
*
|
||||
* document::parser parser;
|
||||
* document::element doc = parser.parse(R"({ "foo": { "a": [ 10, 20, 30 ] }})");
|
||||
* dom::parser parser;
|
||||
* element doc = parser.parse(R"({ "foo": { "a": [ 10, 20, 30 ] }})");
|
||||
* doc["/foo/a/1"] == 20
|
||||
* doc["/"]["foo"]["a"].at(1) == 20
|
||||
* doc[""]["foo"]["a"].at(1) == 20
|
||||
|
@ -342,8 +351,8 @@ public:
|
|||
/**
|
||||
* Get the value associated with the given JSON pointer.
|
||||
*
|
||||
* document::parser parser;
|
||||
* document::element doc = parser.parse(R"({ "foo": { "a": [ 10, 20, 30 ] }})");
|
||||
* 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
|
||||
|
@ -369,7 +378,7 @@ public:
|
|||
*
|
||||
* The key will be matched against **unescaped** JSON:
|
||||
*
|
||||
* document::parser parser;
|
||||
* dom::parser parser;
|
||||
* parser.parse(R"({ "a\n": 1 })")["a\n"].as_uint64_t().value == 1
|
||||
* parser.parse(R"({ "a\n": 1 })")["a\\n"].as_uint64_t().error == NO_SUCH_FIELD
|
||||
*
|
||||
|
@ -392,9 +401,11 @@ public:
|
|||
inline bool dump_raw_tape(std::ostream &out) const noexcept;
|
||||
|
||||
private:
|
||||
really_inline element(const document *_doc, size_t _json_index) noexcept;
|
||||
really_inline element(const document *doc, size_t json_index) noexcept;
|
||||
friend class document;
|
||||
friend struct simdjson_result<document::element>;
|
||||
friend class object;
|
||||
friend class array;
|
||||
friend struct simdjson_result<element>;
|
||||
template<typename T>
|
||||
friend class simdjson::minify;
|
||||
};
|
||||
|
@ -402,12 +413,12 @@ private:
|
|||
/**
|
||||
* Represents a JSON array.
|
||||
*/
|
||||
class document::array : protected internal::tape_ref {
|
||||
class array : protected internal::tape_ref {
|
||||
public:
|
||||
/** Create a new, invalid array */
|
||||
really_inline array() noexcept;
|
||||
|
||||
class iterator : tape_ref {
|
||||
class iterator : protected internal::tape_ref {
|
||||
public:
|
||||
/**
|
||||
* Get the actual value
|
||||
|
@ -426,7 +437,7 @@ public:
|
|||
*/
|
||||
inline bool operator!=(const iterator& other) const noexcept;
|
||||
private:
|
||||
really_inline iterator(const document *_doc, size_t _json_index) noexcept;
|
||||
really_inline iterator(const document *doc, size_t json_index) noexcept;
|
||||
friend class array;
|
||||
};
|
||||
|
||||
|
@ -446,8 +457,8 @@ public:
|
|||
/**
|
||||
* Get the value associated with the given JSON pointer.
|
||||
*
|
||||
* document::parser parser;
|
||||
* document::array a = parser.parse(R"([ { "foo": { "a": [ 10, 20, 30 ] }} ])");
|
||||
* dom::parser parser;
|
||||
* array a = parser.parse(R"([ { "foo": { "a": [ 10, 20, 30 ] }} ])");
|
||||
* a["0/foo/a/1"] == 20
|
||||
* a["0"]["foo"]["a"].at(1) == 20
|
||||
*
|
||||
|
@ -462,8 +473,8 @@ public:
|
|||
/**
|
||||
* Get the value associated with the given JSON pointer.
|
||||
*
|
||||
* document::parser parser;
|
||||
* document::array a = parser.parse(R"([ { "foo": { "a": [ 10, 20, 30 ] }} ])");
|
||||
* dom::parser parser;
|
||||
* array a = parser.parse(R"([ { "foo": { "a": [ 10, 20, 30 ] }} ])");
|
||||
* a["0/foo/a/1"] == 20
|
||||
* a["0"]["foo"]["a"].at(1) == 20
|
||||
*
|
||||
|
@ -478,8 +489,8 @@ public:
|
|||
/**
|
||||
* Get the value associated with the given JSON pointer.
|
||||
*
|
||||
* document::parser parser;
|
||||
* document::array a = parser.parse(R"([ { "foo": { "a": [ 10, 20, 30 ] }} ])");
|
||||
* dom::parser parser;
|
||||
* array a = parser.parse(R"([ { "foo": { "a": [ 10, 20, 30 ] }} ])");
|
||||
* a.at("0/foo/a/1") == 20
|
||||
* a.at("0")["foo"]["a"].at(1) == 20
|
||||
*
|
||||
|
@ -500,7 +511,7 @@ public:
|
|||
inline simdjson_result<element> at(size_t index) const noexcept;
|
||||
|
||||
private:
|
||||
really_inline array(const document *_doc, size_t _json_index) noexcept;
|
||||
really_inline array(const document *doc, size_t json_index) noexcept;
|
||||
friend class element;
|
||||
friend struct simdjson_result<element>;
|
||||
template<typename T>
|
||||
|
@ -510,7 +521,7 @@ private:
|
|||
/**
|
||||
* Represents a JSON object.
|
||||
*/
|
||||
class document::object : protected internal::tape_ref {
|
||||
class object : protected internal::tape_ref {
|
||||
public:
|
||||
/** Create a new, invalid object */
|
||||
really_inline object() noexcept;
|
||||
|
@ -520,7 +531,7 @@ public:
|
|||
/**
|
||||
* Get the actual key/value pair
|
||||
*/
|
||||
inline const document::key_value_pair operator*() const noexcept;
|
||||
inline const key_value_pair operator*() const noexcept;
|
||||
/**
|
||||
* Get the next key/value pair.
|
||||
*
|
||||
|
@ -546,7 +557,7 @@ public:
|
|||
*/
|
||||
inline element value() const noexcept;
|
||||
private:
|
||||
really_inline iterator(const document *_doc, size_t _json_index) noexcept;
|
||||
really_inline iterator(const document *doc, size_t json_index) noexcept;
|
||||
friend class object;
|
||||
};
|
||||
|
||||
|
@ -566,8 +577,8 @@ public:
|
|||
/**
|
||||
* Get the value associated with the given JSON pointer.
|
||||
*
|
||||
* document::parser parser;
|
||||
* document::object obj = parser.parse(R"({ "foo": { "a": [ 10, 20, 30 ] }})");
|
||||
* dom::parser parser;
|
||||
* object obj = parser.parse(R"({ "foo": { "a": [ 10, 20, 30 ] }})");
|
||||
* obj["foo/a/1"] == 20
|
||||
* obj["foo"]["a"].at(1) == 20
|
||||
*
|
||||
|
@ -582,8 +593,8 @@ public:
|
|||
/**
|
||||
* Get the value associated with the given JSON pointer.
|
||||
*
|
||||
* document::parser parser;
|
||||
* document::object obj = parser.parse(R"({ "foo": { "a": [ 10, 20, 30 ] }})");
|
||||
* dom::parser parser;
|
||||
* object obj = parser.parse(R"({ "foo": { "a": [ 10, 20, 30 ] }})");
|
||||
* obj["foo/a/1"] == 20
|
||||
* obj["foo"]["a"].at(1) == 20
|
||||
*
|
||||
|
@ -598,8 +609,8 @@ public:
|
|||
/**
|
||||
* Get the value associated with the given JSON pointer.
|
||||
*
|
||||
* document::parser parser;
|
||||
* document::object obj = parser.parse(R"({ "foo": { "a": [ 10, 20, 30 ] }})");
|
||||
* dom::parser parser;
|
||||
* object obj = parser.parse(R"({ "foo": { "a": [ 10, 20, 30 ] }})");
|
||||
* obj.at("foo/a/1") == 20
|
||||
* obj.at("foo")["a"].at(1) == 20
|
||||
*
|
||||
|
@ -616,7 +627,7 @@ public:
|
|||
*
|
||||
* The key will be matched against **unescaped** JSON:
|
||||
*
|
||||
* document::parser parser;
|
||||
* dom::parser parser;
|
||||
* parser.parse(R"({ "a\n": 1 })")["a\n"].as_uint64_t().value == 1
|
||||
* parser.parse(R"({ "a\n": 1 })")["a\\n"].as_uint64_t().error == NO_SUCH_FIELD
|
||||
*
|
||||
|
@ -636,7 +647,7 @@ public:
|
|||
inline simdjson_result<element> at_key_case_insensitive(const std::string_view &key) const noexcept;
|
||||
|
||||
private:
|
||||
really_inline object(const document *_doc, size_t _json_index) noexcept;
|
||||
really_inline object(const document *doc, size_t json_index) noexcept;
|
||||
friend class element;
|
||||
friend struct simdjson_result<element>;
|
||||
template<typename T>
|
||||
|
@ -646,93 +657,16 @@ private:
|
|||
/**
|
||||
* Key/value pair in an object.
|
||||
*/
|
||||
class document::key_value_pair {
|
||||
class key_value_pair {
|
||||
public:
|
||||
std::string_view key;
|
||||
document::element value;
|
||||
element value;
|
||||
|
||||
private:
|
||||
really_inline key_value_pair(const std::string_view &_key, document::element _value) noexcept;
|
||||
really_inline key_value_pair(const std::string_view &_key, element _value) noexcept;
|
||||
friend class object;
|
||||
};
|
||||
|
||||
/** The result of a JSON navigation that may fail. */
|
||||
template<>
|
||||
struct simdjson_result<document::element> : public internal::simdjson_result_base<document::element> {
|
||||
public:
|
||||
really_inline simdjson_result() noexcept;
|
||||
really_inline simdjson_result(document::element &&value) noexcept;
|
||||
really_inline simdjson_result(error_code error) noexcept;
|
||||
|
||||
/** Whether this is a JSON `null` */
|
||||
inline simdjson_result<bool> is_null() const noexcept;
|
||||
inline simdjson_result<bool> as_bool() const noexcept;
|
||||
inline simdjson_result<std::string_view> as_string() const noexcept;
|
||||
inline simdjson_result<const char *> as_c_str() const noexcept;
|
||||
inline simdjson_result<uint64_t> as_uint64_t() const noexcept;
|
||||
inline simdjson_result<int64_t> as_int64_t() const noexcept;
|
||||
inline simdjson_result<double> as_double() const noexcept;
|
||||
inline simdjson_result<document::array> as_array() const noexcept;
|
||||
inline simdjson_result<document::object> as_object() const noexcept;
|
||||
|
||||
inline simdjson_result<document::element> operator[](const std::string_view &json_pointer) const noexcept;
|
||||
inline simdjson_result<document::element> operator[](const char *json_pointer) const noexcept;
|
||||
inline simdjson_result<document::element> at(const std::string_view &json_pointer) const noexcept;
|
||||
inline simdjson_result<document::element> at(size_t index) const noexcept;
|
||||
inline simdjson_result<document::element> at_key(const std::string_view &key) const noexcept;
|
||||
inline simdjson_result<document::element> at_key_case_insensitive(const std::string_view &key) const noexcept;
|
||||
|
||||
#if SIMDJSON_EXCEPTIONS
|
||||
inline operator bool() const noexcept(false);
|
||||
inline explicit operator const char*() const noexcept(false);
|
||||
inline operator std::string_view() const noexcept(false);
|
||||
inline operator uint64_t() const noexcept(false);
|
||||
inline operator int64_t() const noexcept(false);
|
||||
inline operator double() const noexcept(false);
|
||||
inline operator document::array() const noexcept(false);
|
||||
inline operator document::object() const noexcept(false);
|
||||
#endif // SIMDJSON_EXCEPTIONS
|
||||
};
|
||||
|
||||
/** The result of a JSON conversion that may fail. */
|
||||
template<>
|
||||
struct simdjson_result<document::array> : public internal::simdjson_result_base<document::array> {
|
||||
public:
|
||||
really_inline simdjson_result() noexcept;
|
||||
really_inline simdjson_result(document::array value) noexcept;
|
||||
really_inline simdjson_result(error_code error) noexcept;
|
||||
|
||||
inline simdjson_result<document::element> operator[](const std::string_view &json_pointer) const noexcept;
|
||||
inline simdjson_result<document::element> operator[](const char *json_pointer) const noexcept;
|
||||
inline simdjson_result<document::element> at(const std::string_view &json_pointer) const noexcept;
|
||||
inline simdjson_result<document::element> at(size_t index) const noexcept;
|
||||
|
||||
#if SIMDJSON_EXCEPTIONS
|
||||
inline document::array::iterator begin() const noexcept(false);
|
||||
inline document::array::iterator end() const noexcept(false);
|
||||
#endif // SIMDJSON_EXCEPTIONS
|
||||
};
|
||||
|
||||
/** The result of a JSON conversion that may fail. */
|
||||
template<>
|
||||
struct simdjson_result<document::object> : public internal::simdjson_result_base<document::object> {
|
||||
public:
|
||||
really_inline simdjson_result() noexcept;
|
||||
really_inline simdjson_result(document::object value) noexcept;
|
||||
really_inline simdjson_result(error_code error) noexcept;
|
||||
|
||||
inline simdjson_result<document::element> operator[](const std::string_view &json_pointer) const noexcept;
|
||||
inline simdjson_result<document::element> operator[](const char *json_pointer) const noexcept;
|
||||
inline simdjson_result<document::element> at(const std::string_view &json_pointer) const noexcept;
|
||||
inline simdjson_result<document::element> at_key(const std::string_view &key) const noexcept;
|
||||
inline simdjson_result<document::element> at_key_case_insensitive(const std::string_view &key) const noexcept;
|
||||
|
||||
#if SIMDJSON_EXCEPTIONS
|
||||
inline document::object::iterator begin() const noexcept(false);
|
||||
inline document::object::iterator end() const noexcept(false);
|
||||
#endif // SIMDJSON_EXCEPTIONS
|
||||
};
|
||||
|
||||
/**
|
||||
* A persistent document parser.
|
||||
*
|
||||
|
@ -743,7 +677,7 @@ public:
|
|||
*
|
||||
* @note This is not thread safe: one parser cannot produce two documents at the same time!
|
||||
*/
|
||||
class document::parser {
|
||||
class parser {
|
||||
public:
|
||||
/**
|
||||
* Create a JSON parser.
|
||||
|
@ -767,21 +701,21 @@ public:
|
|||
*
|
||||
* @param other The parser to take. Its capacity is zeroed.
|
||||
*/
|
||||
parser(document::parser &&other) = default;
|
||||
parser(const document::parser &) = delete; // Disallow copying
|
||||
parser(parser &&other) = default;
|
||||
parser(const parser &) = delete; // Disallow copying
|
||||
/**
|
||||
* Take another parser's buffers and state.
|
||||
*
|
||||
* @param other The parser to take. Its capacity is zeroed.
|
||||
*/
|
||||
parser &operator=(document::parser &&other) = default;
|
||||
parser &operator=(const document::parser &) = delete; // Disallow copying
|
||||
parser &operator=(parser &&other) = default;
|
||||
parser &operator=(const parser &) = delete; // Disallow copying
|
||||
|
||||
/**
|
||||
* Load a JSON document from a file and return a reference to it.
|
||||
*
|
||||
* document::parser parser;
|
||||
* const document::element doc = parser.load("jsonexamples/twitter.json");
|
||||
* dom::parser parser;
|
||||
* const element doc = parser.load("jsonexamples/twitter.json");
|
||||
*
|
||||
* ### IMPORTANT: Document Lifetime
|
||||
*
|
||||
|
@ -806,8 +740,8 @@ public:
|
|||
/**
|
||||
* Load a file containing many JSON documents.
|
||||
*
|
||||
* document::parser parser;
|
||||
* for (const document::element doc : parser.parse_many(path)) {
|
||||
* dom::parser parser;
|
||||
* for (const element doc : parser.parse_many(path)) {
|
||||
* cout << std::string(doc["title"]) << endl;
|
||||
* }
|
||||
*
|
||||
|
@ -830,7 +764,7 @@ public:
|
|||
* As with all other simdjson methods, non-exception error handling is readily available through
|
||||
* the same interface, requiring you to check the error before using the document:
|
||||
*
|
||||
* document::parser parser;
|
||||
* dom::parser parser;
|
||||
* for (auto [doc, error] : parser.load_many(path)) {
|
||||
* if (error) { cerr << error << endl; exit(1); }
|
||||
* cout << std::string(doc["title"]) << endl;
|
||||
|
@ -858,13 +792,13 @@ public:
|
|||
* - CAPACITY if the parser does not have enough capacity and batch_size > max_capacity.
|
||||
* - other json errors if parsing fails.
|
||||
*/
|
||||
inline document::stream load_many(const std::string &path, size_t batch_size = DEFAULT_BATCH_SIZE) noexcept;
|
||||
inline stream load_many(const std::string &path, size_t batch_size = DEFAULT_BATCH_SIZE) noexcept;
|
||||
|
||||
/**
|
||||
* Parse a JSON document and return a temporary reference to it.
|
||||
*
|
||||
* document::parser parser;
|
||||
* document::element doc = parser.parse(buf, len);
|
||||
* dom::parser parser;
|
||||
* element doc = parser.parse(buf, len);
|
||||
*
|
||||
* ### IMPORTANT: Document Lifetime
|
||||
*
|
||||
|
@ -900,8 +834,8 @@ public:
|
|||
/**
|
||||
* Parse a JSON document and return a temporary reference to it.
|
||||
*
|
||||
* document::parser parser;
|
||||
* const document::element doc = parser.parse(buf, len);
|
||||
* dom::parser parser;
|
||||
* const element doc = parser.parse(buf, len);
|
||||
*
|
||||
* ### IMPORTANT: Document Lifetime
|
||||
*
|
||||
|
@ -937,8 +871,8 @@ public:
|
|||
/**
|
||||
* Parse a JSON document and return a temporary reference to it.
|
||||
*
|
||||
* document::parser parser;
|
||||
* const document::element doc = parser.parse(s);
|
||||
* dom::parser parser;
|
||||
* const element doc = parser.parse(s);
|
||||
*
|
||||
* ### IMPORTANT: Document Lifetime
|
||||
*
|
||||
|
@ -972,8 +906,8 @@ public:
|
|||
/**
|
||||
* Parse a JSON document and return a temporary reference to it.
|
||||
*
|
||||
* document::parser parser;
|
||||
* const document::element doc = parser.parse(s);
|
||||
* dom::parser parser;
|
||||
* const element doc = parser.parse(s);
|
||||
*
|
||||
* ### IMPORTANT: Document Lifetime
|
||||
*
|
||||
|
@ -1000,8 +934,8 @@ public:
|
|||
/**
|
||||
* Parse a buffer containing many JSON documents.
|
||||
*
|
||||
* document::parser parser;
|
||||
* for (const document::element doc : parser.parse_many(buf, len)) {
|
||||
* dom::parser parser;
|
||||
* for (const element doc : parser.parse_many(buf, len)) {
|
||||
* cout << std::string(doc["title"]) << endl;
|
||||
* }
|
||||
*
|
||||
|
@ -1024,7 +958,7 @@ public:
|
|||
* As with all other simdjson methods, non-exception error handling is readily available through
|
||||
* the same interface, requiring you to check the error before using the document:
|
||||
*
|
||||
* document::parser parser;
|
||||
* dom::parser parser;
|
||||
* for (auto [doc, error] : parser.parse_many(buf, len)) {
|
||||
* if (error) { cerr << error << endl; exit(1); }
|
||||
* cout << std::string(doc["title"]) << endl;
|
||||
|
@ -1062,8 +996,8 @@ public:
|
|||
/**
|
||||
* Parse a buffer containing many JSON documents.
|
||||
*
|
||||
* document::parser parser;
|
||||
* for (const document::element doc : parser.parse_many(buf, len)) {
|
||||
* dom::parser parser;
|
||||
* for (const element doc : parser.parse_many(buf, len)) {
|
||||
* cout << std::string(doc["title"]) << endl;
|
||||
* }
|
||||
*
|
||||
|
@ -1086,7 +1020,7 @@ public:
|
|||
* As with all other simdjson methods, non-exception error handling is readily available through
|
||||
* the same interface, requiring you to check the error before using the document:
|
||||
*
|
||||
* document::parser parser;
|
||||
* dom::parser parser;
|
||||
* for (auto [doc, error] : parser.parse_many(buf, len)) {
|
||||
* if (error) { cerr << error << endl; exit(1); }
|
||||
* cout << std::string(doc["title"]) << endl;
|
||||
|
@ -1124,8 +1058,8 @@ public:
|
|||
/**
|
||||
* Parse a buffer containing many JSON documents.
|
||||
*
|
||||
* document::parser parser;
|
||||
* for (const document::element doc : parser.parse_many(buf, len)) {
|
||||
* dom::parser parser;
|
||||
* for (const element doc : parser.parse_many(buf, len)) {
|
||||
* cout << std::string(doc["title"]) << endl;
|
||||
* }
|
||||
*
|
||||
|
@ -1148,7 +1082,7 @@ public:
|
|||
* As with all other simdjson methods, non-exception error handling is readily available through
|
||||
* the same interface, requiring you to check the error before using the document:
|
||||
*
|
||||
* document::parser parser;
|
||||
* dom::parser parser;
|
||||
* for (auto [doc, error] : parser.parse_many(buf, len)) {
|
||||
* if (error) { cerr << error << endl; exit(1); }
|
||||
* cout << std::string(doc["title"]) << endl;
|
||||
|
@ -1185,8 +1119,8 @@ public:
|
|||
/**
|
||||
* Parse a buffer containing many JSON documents.
|
||||
*
|
||||
* document::parser parser;
|
||||
* for (const document::element doc : parser.parse_many(buf, len)) {
|
||||
* dom::parser parser;
|
||||
* for (const element doc : parser.parse_many(buf, len)) {
|
||||
* cout << std::string(doc["title"]) << endl;
|
||||
* }
|
||||
*
|
||||
|
@ -1209,7 +1143,7 @@ public:
|
|||
* As with all other simdjson methods, non-exception error handling is readily available through
|
||||
* the same interface, requiring you to check the error before using the document:
|
||||
*
|
||||
* document::parser parser;
|
||||
* dom::parser parser;
|
||||
* for (auto [doc, error] : parser.parse_many(buf, len)) {
|
||||
* if (error) { cerr << error << endl; exit(1); }
|
||||
* cout << std::string(doc["title"]) << endl;
|
||||
|
@ -1449,11 +1383,15 @@ private:
|
|||
friend class stream;
|
||||
}; // class parser
|
||||
|
||||
} // namespace simdjson::dom
|
||||
|
||||
namespace simdjson {
|
||||
|
||||
/**
|
||||
* Minifies a JSON element or document, printing the smallest possible valid JSON.
|
||||
*
|
||||
* document::parser parser;
|
||||
* document::element doc = parser.parse(" [ 1 , 2 , 3 ] "_padded);
|
||||
* dom::parser parser;
|
||||
* element doc = parser.parse(" [ 1 , 2 , 3 ] "_padded);
|
||||
* cout << minify(doc) << endl; // prints [1,2,3]
|
||||
*
|
||||
*/
|
||||
|
@ -1490,6 +1428,11 @@ private:
|
|||
template<typename T>
|
||||
inline std::ostream& operator<<(std::ostream& out, minify<T> formatter) { return formatter.print(out); }
|
||||
|
||||
namespace dom {
|
||||
|
||||
// << operators need to be in the same namespace as the class being output, so C++ can find them
|
||||
// automatically
|
||||
|
||||
/**
|
||||
* Print JSON to an output stream.
|
||||
*
|
||||
|
@ -1499,7 +1442,7 @@ inline std::ostream& operator<<(std::ostream& out, minify<T> formatter) { return
|
|||
* @param value The value to print.
|
||||
* @throw if there is an error with the underlying output stream. simdjson itself will not throw.
|
||||
*/
|
||||
inline std::ostream& operator<<(std::ostream& out, const document::element &value) { return out << minify(value); };
|
||||
inline std::ostream& operator<<(std::ostream& out, const element &value) { return out << minify(value); };
|
||||
/**
|
||||
* Print JSON to an output stream.
|
||||
*
|
||||
|
@ -1509,7 +1452,7 @@ inline std::ostream& operator<<(std::ostream& out, const document::element &valu
|
|||
* @param value The value to print.
|
||||
* @throw if there is an error with the underlying output stream. simdjson itself will not throw.
|
||||
*/
|
||||
inline std::ostream& operator<<(std::ostream& out, const document::array &value) { return out << minify(value); }
|
||||
inline std::ostream& operator<<(std::ostream& out, const array &value) { return out << minify(value); }
|
||||
/**
|
||||
* Print JSON to an output stream.
|
||||
*
|
||||
|
@ -1519,7 +1462,7 @@ inline std::ostream& operator<<(std::ostream& out, const document::array &value)
|
|||
* @param value The value to print.
|
||||
* @throw if there is an error with the underlying output stream. simdjson itself will not throw.
|
||||
*/
|
||||
inline std::ostream& operator<<(std::ostream& out, const document::object &value) { return out << minify(value); }
|
||||
inline std::ostream& operator<<(std::ostream& out, const object &value) { return out << minify(value); }
|
||||
/**
|
||||
* Print JSON to an output stream.
|
||||
*
|
||||
|
@ -1529,7 +1472,9 @@ inline std::ostream& operator<<(std::ostream& out, const document::object &value
|
|||
* @param value The value to print.
|
||||
* @throw if there is an error with the underlying output stream. simdjson itself will not throw.
|
||||
*/
|
||||
inline std::ostream& operator<<(std::ostream& out, const document::key_value_pair &value) { return out << minify(value); }
|
||||
inline std::ostream& operator<<(std::ostream& out, const key_value_pair &value) { return out << minify(value); }
|
||||
|
||||
} // namespace dom
|
||||
|
||||
#if SIMDJSON_EXCEPTIONS
|
||||
|
||||
|
@ -1544,7 +1489,7 @@ inline std::ostream& operator<<(std::ostream& out, const document::key_value_pai
|
|||
* underlying output stream, that error will be propagated (simdjson_error will not be
|
||||
* thrown).
|
||||
*/
|
||||
inline std::ostream& operator<<(std::ostream& out, const simdjson_result<document::element> &value) noexcept(false) { return out << minify(value); }
|
||||
inline std::ostream& operator<<(std::ostream& out, const simdjson_result<dom::element> &value) noexcept(false) { return out << minify(value); }
|
||||
/**
|
||||
* Print JSON to an output stream.
|
||||
*
|
||||
|
@ -1556,7 +1501,7 @@ inline std::ostream& operator<<(std::ostream& out, const simdjson_result<documen
|
|||
* underlying output stream, that error will be propagated (simdjson_error will not be
|
||||
* thrown).
|
||||
*/
|
||||
inline std::ostream& operator<<(std::ostream& out, const simdjson_result<document::array> &value) noexcept(false) { return out << minify(value); }
|
||||
inline std::ostream& operator<<(std::ostream& out, const simdjson_result<dom::array> &value) noexcept(false) { return out << minify(value); }
|
||||
/**
|
||||
* Print JSON to an output stream.
|
||||
*
|
||||
|
@ -1568,10 +1513,87 @@ inline std::ostream& operator<<(std::ostream& out, const simdjson_result<documen
|
|||
* underlying output stream, that error will be propagated (simdjson_error will not be
|
||||
* thrown).
|
||||
*/
|
||||
inline std::ostream& operator<<(std::ostream& out, const simdjson_result<document::object> &value) noexcept(false) { return out << minify(value); }
|
||||
inline std::ostream& operator<<(std::ostream& out, const simdjson_result<dom::object> &value) noexcept(false) { return out << minify(value); }
|
||||
|
||||
#endif
|
||||
|
||||
/** The result of a JSON navigation that may fail. */
|
||||
template<>
|
||||
struct simdjson_result<dom::element> : public internal::simdjson_result_base<dom::element> {
|
||||
public:
|
||||
really_inline simdjson_result() noexcept;
|
||||
really_inline simdjson_result(dom::element &&value) noexcept;
|
||||
really_inline simdjson_result(error_code error) noexcept;
|
||||
|
||||
/** Whether this is a JSON `null` */
|
||||
inline simdjson_result<bool> is_null() const noexcept;
|
||||
inline simdjson_result<bool> as_bool() const noexcept;
|
||||
inline simdjson_result<std::string_view> as_string() const noexcept;
|
||||
inline simdjson_result<const char *> as_c_str() const noexcept;
|
||||
inline simdjson_result<uint64_t> as_uint64_t() const noexcept;
|
||||
inline simdjson_result<int64_t> as_int64_t() const noexcept;
|
||||
inline simdjson_result<double> as_double() const noexcept;
|
||||
inline simdjson_result<dom::array> as_array() const noexcept;
|
||||
inline simdjson_result<dom::object> as_object() const noexcept;
|
||||
|
||||
inline simdjson_result<dom::element> operator[](const std::string_view &json_pointer) const noexcept;
|
||||
inline simdjson_result<dom::element> operator[](const char *json_pointer) const noexcept;
|
||||
inline simdjson_result<dom::element> at(const std::string_view &json_pointer) const noexcept;
|
||||
inline simdjson_result<dom::element> at(size_t index) const noexcept;
|
||||
inline simdjson_result<dom::element> at_key(const std::string_view &key) const noexcept;
|
||||
inline simdjson_result<dom::element> at_key_case_insensitive(const std::string_view &key) const noexcept;
|
||||
|
||||
#if SIMDJSON_EXCEPTIONS
|
||||
inline operator bool() const noexcept(false);
|
||||
inline explicit operator const char*() const noexcept(false);
|
||||
inline operator std::string_view() const noexcept(false);
|
||||
inline operator uint64_t() const noexcept(false);
|
||||
inline operator int64_t() const noexcept(false);
|
||||
inline operator double() const noexcept(false);
|
||||
inline operator dom::array() const noexcept(false);
|
||||
inline operator dom::object() const noexcept(false);
|
||||
#endif // SIMDJSON_EXCEPTIONS
|
||||
};
|
||||
|
||||
/** The result of a JSON conversion that may fail. */
|
||||
template<>
|
||||
struct simdjson_result<dom::array> : public internal::simdjson_result_base<dom::array> {
|
||||
public:
|
||||
really_inline simdjson_result() noexcept;
|
||||
really_inline simdjson_result(dom::array value) noexcept;
|
||||
really_inline simdjson_result(error_code error) noexcept;
|
||||
|
||||
inline simdjson_result<dom::element> operator[](const std::string_view &json_pointer) const noexcept;
|
||||
inline simdjson_result<dom::element> operator[](const char *json_pointer) const noexcept;
|
||||
inline simdjson_result<dom::element> at(const std::string_view &json_pointer) const noexcept;
|
||||
inline simdjson_result<dom::element> at(size_t index) const noexcept;
|
||||
|
||||
#if SIMDJSON_EXCEPTIONS
|
||||
inline dom::array::iterator begin() const noexcept(false);
|
||||
inline dom::array::iterator end() const noexcept(false);
|
||||
#endif // SIMDJSON_EXCEPTIONS
|
||||
};
|
||||
|
||||
/** The result of a JSON conversion that may fail. */
|
||||
template<>
|
||||
struct simdjson_result<dom::object> : public internal::simdjson_result_base<dom::object> {
|
||||
public:
|
||||
really_inline simdjson_result() noexcept;
|
||||
really_inline simdjson_result(dom::object value) noexcept;
|
||||
really_inline simdjson_result(error_code error) noexcept;
|
||||
|
||||
inline simdjson_result<dom::element> operator[](const std::string_view &json_pointer) const noexcept;
|
||||
inline simdjson_result<dom::element> operator[](const char *json_pointer) const noexcept;
|
||||
inline simdjson_result<dom::element> at(const std::string_view &json_pointer) const noexcept;
|
||||
inline simdjson_result<dom::element> at_key(const std::string_view &key) const noexcept;
|
||||
inline simdjson_result<dom::element> at_key_case_insensitive(const std::string_view &key) const noexcept;
|
||||
|
||||
#if SIMDJSON_EXCEPTIONS
|
||||
inline dom::object::iterator begin() const noexcept(false);
|
||||
inline dom::object::iterator end() const noexcept(false);
|
||||
#endif // SIMDJSON_EXCEPTIONS
|
||||
};
|
||||
|
||||
} // namespace simdjson
|
||||
|
||||
#endif // SIMDJSON_DOCUMENT_H
|
|
@ -4,15 +4,15 @@
|
|||
#include <thread>
|
||||
#include "simdjson/document.h"
|
||||
|
||||
namespace simdjson {
|
||||
namespace simdjson::dom {
|
||||
|
||||
/**
|
||||
* A forward-only stream of documents.
|
||||
*
|
||||
* Produced by document::parser::parse_many.
|
||||
* Produced by parser::parse_many.
|
||||
*
|
||||
*/
|
||||
class document::stream {
|
||||
class stream {
|
||||
public:
|
||||
really_inline ~stream() noexcept;
|
||||
|
||||
|
@ -55,11 +55,11 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
stream &operator=(const document::stream &) = delete; // Disallow copying
|
||||
stream &operator=(const stream &) = delete; // Disallow copying
|
||||
|
||||
stream(document::stream &other) = delete; // Disallow copying
|
||||
stream(stream &other) = delete; // Disallow copying
|
||||
|
||||
really_inline stream(document::parser &parser, const uint8_t *buf, size_t len, size_t batch_size, error_code error = SUCCESS) noexcept;
|
||||
really_inline stream(dom::parser &parser, const uint8_t *buf, size_t len, size_t batch_size, error_code error = SUCCESS) noexcept;
|
||||
|
||||
/**
|
||||
* Parse the next document found in the buffer previously given to stream.
|
||||
|
@ -116,7 +116,7 @@ private:
|
|||
|
||||
inline size_t remaining() const { return _len - buf_start; }
|
||||
|
||||
document::parser &parser;
|
||||
dom::parser &parser;
|
||||
const uint8_t *_buf;
|
||||
const size_t _len;
|
||||
size_t _batch_size; // this is actually variable!
|
||||
|
@ -133,10 +133,11 @@ private:
|
|||
#ifdef SIMDJSON_THREADS_ENABLED
|
||||
error_code stage1_is_ok_thread{SUCCESS};
|
||||
std::thread stage_1_thread;
|
||||
document::parser parser_thread;
|
||||
dom::parser parser_thread;
|
||||
#endif
|
||||
friend class document::parser;
|
||||
}; // class document::stream
|
||||
friend class dom::parser;
|
||||
}; // class stream
|
||||
|
||||
} // end of namespace simdjson::dom
|
||||
|
||||
} // end of namespace simdjson
|
||||
#endif // SIMDJSON_DOCUMENT_STREAM_H
|
||||
|
|
|
@ -43,7 +43,7 @@ enum error_code {
|
|||
/**
|
||||
* Get the error message for the given error code.
|
||||
*
|
||||
* document::parser parser;
|
||||
* dom::parser parser;
|
||||
* auto [doc, error] = parser.parse("foo");
|
||||
* if (error) { printf("Error: %s\n", error_message(error)); }
|
||||
*
|
||||
|
|
|
@ -54,7 +54,7 @@ public:
|
|||
* @param parser the parser with the buffers to use. *MUST* have allocated up to at least len capacity.
|
||||
* @return the error code, or SUCCESS if there was no error.
|
||||
*/
|
||||
WARN_UNUSED virtual error_code parse(const uint8_t *buf, size_t len, document::parser &parser) const noexcept = 0;
|
||||
WARN_UNUSED virtual error_code parse(const uint8_t *buf, size_t len, dom::parser &parser) const noexcept = 0;
|
||||
|
||||
/**
|
||||
* Run a full document parse (ensure_capacity, stage1 and stage2).
|
||||
|
@ -77,10 +77,10 @@ public:
|
|||
* @param buf the json document to parse. *MUST* be allocated up to len + SIMDJSON_PADDING bytes.
|
||||
* @param len the length of the json document.
|
||||
* @param parser the parser with the buffers to use. *MUST* have allocated up to at least len capacity.
|
||||
* @param streaming whether this is being called by document::parser::parse_many.
|
||||
* @param streaming whether this is being called by parser::parse_many.
|
||||
* @return the error code, or SUCCESS if there was no error.
|
||||
*/
|
||||
WARN_UNUSED virtual error_code stage1(const uint8_t *buf, size_t len, document::parser &parser, bool streaming) const noexcept = 0;
|
||||
WARN_UNUSED virtual error_code stage1(const uint8_t *buf, size_t len, dom::parser &parser, bool streaming) const noexcept = 0;
|
||||
|
||||
/**
|
||||
* Stage 2 of the document parser.
|
||||
|
@ -92,10 +92,10 @@ public:
|
|||
* @param parser the parser with the buffers to use. *MUST* have allocated up to at least len capacity.
|
||||
* @return the error code, or SUCCESS if there was no error.
|
||||
*/
|
||||
WARN_UNUSED virtual error_code stage2(const uint8_t *buf, size_t len, document::parser &parser) const noexcept = 0;
|
||||
WARN_UNUSED virtual error_code stage2(const uint8_t *buf, size_t len, dom::parser &parser) const noexcept = 0;
|
||||
|
||||
/**
|
||||
* Stage 2 of the document parser for document::parser::parse_many.
|
||||
* Stage 2 of the document parser for parser::parse_many.
|
||||
*
|
||||
* Overridden by each implementation.
|
||||
*
|
||||
|
@ -105,7 +105,7 @@ public:
|
|||
* @param next_json the next structural index. Start this at 0 the first time, and it will be updated to the next value to pass each time.
|
||||
* @return the error code, SUCCESS if there was no error, or SUCCESS_AND_HAS_MORE if there was no error and stage2 can be called again.
|
||||
*/
|
||||
WARN_UNUSED virtual error_code stage2(const uint8_t *buf, size_t len, document::parser &parser, size_t &next_json) const noexcept = 0;
|
||||
WARN_UNUSED virtual error_code stage2(const uint8_t *buf, size_t len, dom::parser &parser, size_t &next_json) const noexcept = 0;
|
||||
|
||||
protected:
|
||||
really_inline implementation(
|
||||
|
@ -192,19 +192,19 @@ public:
|
|||
const std::string& name() const noexcept final { return set_best()->name(); }
|
||||
const std::string& description() const noexcept final { return set_best()->description(); }
|
||||
uint32_t required_instruction_sets() const noexcept final { return set_best()->required_instruction_sets(); }
|
||||
WARN_UNUSED error_code parse(const uint8_t *buf, size_t len, document::parser &parser) const noexcept final {
|
||||
WARN_UNUSED error_code parse(const uint8_t *buf, size_t len, dom::parser &parser) const noexcept final {
|
||||
return set_best()->parse(buf, len, parser);
|
||||
}
|
||||
WARN_UNUSED error_code minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept final {
|
||||
return set_best()->minify(buf, len, dst, dst_len);
|
||||
}
|
||||
WARN_UNUSED error_code stage1(const uint8_t *buf, size_t len, document::parser &parser, bool streaming) const noexcept final {
|
||||
WARN_UNUSED error_code stage1(const uint8_t *buf, size_t len, dom::parser &parser, bool streaming) const noexcept final {
|
||||
return set_best()->stage1(buf, len, parser, streaming);
|
||||
}
|
||||
WARN_UNUSED error_code stage2(const uint8_t *buf, size_t len, document::parser &parser) const noexcept final {
|
||||
WARN_UNUSED error_code stage2(const uint8_t *buf, size_t len, dom::parser &parser) const noexcept final {
|
||||
return set_best()->stage2(buf, len, parser);
|
||||
}
|
||||
WARN_UNUSED error_code stage2(const uint8_t *buf, size_t len, document::parser &parser, size_t &next_json) const noexcept final {
|
||||
WARN_UNUSED error_code stage2(const uint8_t *buf, size_t len, dom::parser &parser, size_t &next_json) const noexcept final {
|
||||
return set_best()->stage2(buf, len, parser, next_json);
|
||||
}
|
||||
|
||||
|
|
|
@ -15,193 +15,197 @@
|
|||
namespace simdjson {
|
||||
|
||||
//
|
||||
// simdjson_result<document::element> inline implementation
|
||||
// simdjson_result<dom::element> inline implementation
|
||||
//
|
||||
really_inline simdjson_result<document::element>::simdjson_result() noexcept
|
||||
: internal::simdjson_result_base<document::element>() {}
|
||||
really_inline simdjson_result<document::element>::simdjson_result(document::element &&value) noexcept
|
||||
: internal::simdjson_result_base<document::element>(std::forward<document::element>(value)) {}
|
||||
really_inline simdjson_result<document::element>::simdjson_result(error_code error) noexcept
|
||||
: internal::simdjson_result_base<document::element>(error) {}
|
||||
inline simdjson_result<bool> simdjson_result<document::element>::is_null() const noexcept {
|
||||
really_inline simdjson_result<dom::element>::simdjson_result() noexcept
|
||||
: internal::simdjson_result_base<dom::element>() {}
|
||||
really_inline simdjson_result<dom::element>::simdjson_result(dom::element &&value) noexcept
|
||||
: internal::simdjson_result_base<dom::element>(std::forward<dom::element>(value)) {}
|
||||
really_inline simdjson_result<dom::element>::simdjson_result(error_code error) noexcept
|
||||
: internal::simdjson_result_base<dom::element>(error) {}
|
||||
inline simdjson_result<bool> simdjson_result<dom::element>::is_null() const noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.is_null();
|
||||
}
|
||||
inline simdjson_result<bool> simdjson_result<document::element>::as_bool() const noexcept {
|
||||
inline simdjson_result<bool> simdjson_result<dom::element>::as_bool() const noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.as_bool();
|
||||
}
|
||||
inline simdjson_result<const char*> simdjson_result<document::element>::as_c_str() const noexcept {
|
||||
inline simdjson_result<const char*> simdjson_result<dom::element>::as_c_str() const noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.as_c_str();
|
||||
}
|
||||
inline simdjson_result<std::string_view> simdjson_result<document::element>::as_string() const noexcept {
|
||||
inline simdjson_result<std::string_view> simdjson_result<dom::element>::as_string() const noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.as_string();
|
||||
}
|
||||
inline simdjson_result<uint64_t> simdjson_result<document::element>::as_uint64_t() const noexcept {
|
||||
inline simdjson_result<uint64_t> simdjson_result<dom::element>::as_uint64_t() const noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.as_uint64_t();
|
||||
}
|
||||
inline simdjson_result<int64_t> simdjson_result<document::element>::as_int64_t() const noexcept {
|
||||
inline simdjson_result<int64_t> simdjson_result<dom::element>::as_int64_t() const noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.as_int64_t();
|
||||
}
|
||||
inline simdjson_result<double> simdjson_result<document::element>::as_double() const noexcept {
|
||||
inline simdjson_result<double> simdjson_result<dom::element>::as_double() const noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.as_double();
|
||||
}
|
||||
inline simdjson_result<document::array> simdjson_result<document::element>::as_array() const noexcept {
|
||||
inline simdjson_result<dom::array> simdjson_result<dom::element>::as_array() const noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.as_array();
|
||||
}
|
||||
inline simdjson_result<document::object> simdjson_result<document::element>::as_object() const noexcept {
|
||||
inline simdjson_result<dom::object> simdjson_result<dom::element>::as_object() const noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.as_object();
|
||||
}
|
||||
|
||||
inline simdjson_result<document::element> simdjson_result<document::element>::operator[](const std::string_view &json_pointer) const noexcept {
|
||||
inline simdjson_result<dom::element> simdjson_result<dom::element>::operator[](const std::string_view &json_pointer) const noexcept {
|
||||
if (error()) { return *this; }
|
||||
return first[json_pointer];
|
||||
}
|
||||
inline simdjson_result<document::element> simdjson_result<document::element>::operator[](const char *json_pointer) const noexcept {
|
||||
inline simdjson_result<dom::element> simdjson_result<dom::element>::operator[](const char *json_pointer) const noexcept {
|
||||
if (error()) { return *this; }
|
||||
return first[json_pointer];
|
||||
}
|
||||
inline simdjson_result<document::element> simdjson_result<document::element>::at(const std::string_view &json_pointer) const noexcept {
|
||||
inline simdjson_result<dom::element> simdjson_result<dom::element>::at(const std::string_view &json_pointer) const noexcept {
|
||||
if (error()) { return *this; }
|
||||
return first.at(json_pointer);
|
||||
}
|
||||
inline simdjson_result<document::element> simdjson_result<document::element>::at(size_t index) const noexcept {
|
||||
inline simdjson_result<dom::element> simdjson_result<dom::element>::at(size_t index) const noexcept {
|
||||
if (error()) { return *this; }
|
||||
return first.at(index);
|
||||
}
|
||||
inline simdjson_result<document::element> simdjson_result<document::element>::at_key(const std::string_view &key) const noexcept {
|
||||
inline simdjson_result<dom::element> simdjson_result<dom::element>::at_key(const std::string_view &key) const noexcept {
|
||||
if (error()) { return *this; }
|
||||
return first.at_key(key);
|
||||
}
|
||||
inline simdjson_result<document::element> simdjson_result<document::element>::at_key_case_insensitive(const std::string_view &key) const noexcept {
|
||||
inline simdjson_result<dom::element> simdjson_result<dom::element>::at_key_case_insensitive(const std::string_view &key) const noexcept {
|
||||
if (error()) { return *this; }
|
||||
return first.at_key_case_insensitive(key);
|
||||
}
|
||||
|
||||
#if SIMDJSON_EXCEPTIONS
|
||||
|
||||
inline simdjson_result<document::element>::operator bool() const noexcept(false) {
|
||||
inline simdjson_result<dom::element>::operator bool() const noexcept(false) {
|
||||
return as_bool();
|
||||
}
|
||||
inline simdjson_result<document::element>::operator const char *() const noexcept(false) {
|
||||
inline simdjson_result<dom::element>::operator const char *() const noexcept(false) {
|
||||
return as_c_str();
|
||||
}
|
||||
inline simdjson_result<document::element>::operator std::string_view() const noexcept(false) {
|
||||
inline simdjson_result<dom::element>::operator std::string_view() const noexcept(false) {
|
||||
return as_string();
|
||||
}
|
||||
inline simdjson_result<document::element>::operator uint64_t() const noexcept(false) {
|
||||
inline simdjson_result<dom::element>::operator uint64_t() const noexcept(false) {
|
||||
return as_uint64_t();
|
||||
}
|
||||
inline simdjson_result<document::element>::operator int64_t() const noexcept(false) {
|
||||
inline simdjson_result<dom::element>::operator int64_t() const noexcept(false) {
|
||||
return as_int64_t();
|
||||
}
|
||||
inline simdjson_result<document::element>::operator double() const noexcept(false) {
|
||||
inline simdjson_result<dom::element>::operator double() const noexcept(false) {
|
||||
return as_double();
|
||||
}
|
||||
inline simdjson_result<document::element>::operator document::array() const noexcept(false) {
|
||||
inline simdjson_result<dom::element>::operator dom::array() const noexcept(false) {
|
||||
return as_array();
|
||||
}
|
||||
inline simdjson_result<document::element>::operator document::object() const noexcept(false) {
|
||||
inline simdjson_result<dom::element>::operator dom::object() const noexcept(false) {
|
||||
return as_object();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
// simdjson_result<document::array> inline implementation
|
||||
// simdjson_result<dom::array> inline implementation
|
||||
//
|
||||
really_inline simdjson_result<document::array>::simdjson_result() noexcept
|
||||
: internal::simdjson_result_base<document::array>() {}
|
||||
really_inline simdjson_result<document::array>::simdjson_result(document::array value) noexcept
|
||||
: internal::simdjson_result_base<document::array>(std::forward<document::array>(value)) {}
|
||||
really_inline simdjson_result<document::array>::simdjson_result(error_code error) noexcept
|
||||
: internal::simdjson_result_base<document::array>(error) {}
|
||||
really_inline simdjson_result<dom::array>::simdjson_result() noexcept
|
||||
: internal::simdjson_result_base<dom::array>() {}
|
||||
really_inline simdjson_result<dom::array>::simdjson_result(dom::array value) noexcept
|
||||
: internal::simdjson_result_base<dom::array>(std::forward<dom::array>(value)) {}
|
||||
really_inline simdjson_result<dom::array>::simdjson_result(error_code error) noexcept
|
||||
: internal::simdjson_result_base<dom::array>(error) {}
|
||||
|
||||
#if SIMDJSON_EXCEPTIONS
|
||||
|
||||
inline document::array::iterator simdjson_result<document::array>::begin() const noexcept(false) {
|
||||
inline dom::array::iterator simdjson_result<dom::array>::begin() const noexcept(false) {
|
||||
if (error()) { throw simdjson_error(error()); }
|
||||
return first.begin();
|
||||
}
|
||||
inline document::array::iterator simdjson_result<document::array>::end() const noexcept(false) {
|
||||
inline dom::array::iterator simdjson_result<dom::array>::end() const noexcept(false) {
|
||||
if (error()) { throw simdjson_error(error()); }
|
||||
return first.end();
|
||||
}
|
||||
|
||||
#endif // SIMDJSON_EXCEPTIONS
|
||||
|
||||
inline simdjson_result<document::element> simdjson_result<document::array>::operator[](const std::string_view &json_pointer) const noexcept {
|
||||
inline simdjson_result<dom::element> simdjson_result<dom::array>::operator[](const std::string_view &json_pointer) const noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.at(json_pointer);
|
||||
}
|
||||
inline simdjson_result<document::element> simdjson_result<document::array>::operator[](const char *json_pointer) const noexcept {
|
||||
inline simdjson_result<dom::element> simdjson_result<dom::array>::operator[](const char *json_pointer) const noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.at(json_pointer);
|
||||
}
|
||||
inline simdjson_result<document::element> simdjson_result<document::array>::at(const std::string_view &json_pointer) const noexcept {
|
||||
inline simdjson_result<dom::element> simdjson_result<dom::array>::at(const std::string_view &json_pointer) const noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.at(json_pointer);
|
||||
}
|
||||
inline simdjson_result<document::element> simdjson_result<document::array>::at(size_t index) const noexcept {
|
||||
inline simdjson_result<dom::element> simdjson_result<dom::array>::at(size_t index) const noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.at(index);
|
||||
}
|
||||
|
||||
//
|
||||
// simdjson_result<document::object> inline implementation
|
||||
// simdjson_result<dom::object> inline implementation
|
||||
//
|
||||
really_inline simdjson_result<document::object>::simdjson_result() noexcept
|
||||
: internal::simdjson_result_base<document::object>() {}
|
||||
really_inline simdjson_result<document::object>::simdjson_result(document::object value) noexcept
|
||||
: internal::simdjson_result_base<document::object>(std::forward<document::object>(value)) {}
|
||||
really_inline simdjson_result<document::object>::simdjson_result(error_code error) noexcept
|
||||
: internal::simdjson_result_base<document::object>(error) {}
|
||||
really_inline simdjson_result<dom::object>::simdjson_result() noexcept
|
||||
: internal::simdjson_result_base<dom::object>() {}
|
||||
really_inline simdjson_result<dom::object>::simdjson_result(dom::object value) noexcept
|
||||
: internal::simdjson_result_base<dom::object>(std::forward<dom::object>(value)) {}
|
||||
really_inline simdjson_result<dom::object>::simdjson_result(error_code error) noexcept
|
||||
: internal::simdjson_result_base<dom::object>(error) {}
|
||||
|
||||
inline simdjson_result<document::element> simdjson_result<document::object>::operator[](const std::string_view &json_pointer) const noexcept {
|
||||
inline simdjson_result<dom::element> simdjson_result<dom::object>::operator[](const std::string_view &json_pointer) const noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first[json_pointer];
|
||||
}
|
||||
inline simdjson_result<document::element> simdjson_result<document::object>::operator[](const char *json_pointer) const noexcept {
|
||||
inline simdjson_result<dom::element> simdjson_result<dom::object>::operator[](const char *json_pointer) const noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first[json_pointer];
|
||||
}
|
||||
inline simdjson_result<document::element> simdjson_result<document::object>::at(const std::string_view &json_pointer) const noexcept {
|
||||
inline simdjson_result<dom::element> simdjson_result<dom::object>::at(const std::string_view &json_pointer) const noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.at(json_pointer);
|
||||
}
|
||||
inline simdjson_result<document::element> simdjson_result<document::object>::at_key(const std::string_view &key) const noexcept {
|
||||
inline simdjson_result<dom::element> simdjson_result<dom::object>::at_key(const std::string_view &key) const noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.at_key(key);
|
||||
}
|
||||
inline simdjson_result<document::element> simdjson_result<document::object>::at_key_case_insensitive(const std::string_view &key) const noexcept {
|
||||
inline simdjson_result<dom::element> simdjson_result<dom::object>::at_key_case_insensitive(const std::string_view &key) const noexcept {
|
||||
if (error()) { return error(); }
|
||||
return first.at_key_case_insensitive(key);
|
||||
}
|
||||
|
||||
#if SIMDJSON_EXCEPTIONS
|
||||
|
||||
inline document::object::iterator simdjson_result<document::object>::begin() const noexcept(false) {
|
||||
inline dom::object::iterator simdjson_result<dom::object>::begin() const noexcept(false) {
|
||||
if (error()) { throw simdjson_error(error()); }
|
||||
return first.begin();
|
||||
}
|
||||
inline document::object::iterator simdjson_result<document::object>::end() const noexcept(false) {
|
||||
inline dom::object::iterator simdjson_result<dom::object>::end() const noexcept(false) {
|
||||
if (error()) { throw simdjson_error(error()); }
|
||||
return first.end();
|
||||
}
|
||||
|
||||
#endif // SIMDJSON_EXCEPTIONS
|
||||
|
||||
} // namespace simdjson
|
||||
|
||||
namespace simdjson::dom {
|
||||
|
||||
//
|
||||
// document inline implementation
|
||||
//
|
||||
inline document::element document::root() const noexcept {
|
||||
inline element document::root() const noexcept {
|
||||
return element(this, 1);
|
||||
}
|
||||
|
||||
|
@ -325,23 +329,23 @@ inline bool document::dump_raw_tape(std::ostream &os) const noexcept {
|
|||
}
|
||||
|
||||
//
|
||||
// document::parser inline implementation
|
||||
// parser inline implementation
|
||||
//
|
||||
really_inline document::parser::parser(size_t max_capacity, size_t max_depth) noexcept
|
||||
really_inline parser::parser(size_t max_capacity, size_t max_depth) noexcept
|
||||
: _max_capacity{max_capacity}, _max_depth{max_depth}, loaded_bytes(nullptr, &aligned_free_char) {}
|
||||
inline bool document::parser::is_valid() const noexcept { return valid; }
|
||||
inline int document::parser::get_error_code() const noexcept { return error; }
|
||||
inline std::string document::parser::get_error_message() const noexcept { return error_message(int(error)); }
|
||||
inline bool document::parser::print_json(std::ostream &os) const noexcept {
|
||||
inline bool parser::is_valid() const noexcept { return valid; }
|
||||
inline int parser::get_error_code() const noexcept { return error; }
|
||||
inline std::string parser::get_error_message() const noexcept { return error_message(int(error)); }
|
||||
inline bool parser::print_json(std::ostream &os) const noexcept {
|
||||
if (!valid) { return false; }
|
||||
os << doc.root();
|
||||
return true;
|
||||
}
|
||||
inline bool document::parser::dump_raw_tape(std::ostream &os) const noexcept {
|
||||
inline bool parser::dump_raw_tape(std::ostream &os) const noexcept {
|
||||
return valid ? doc.dump_raw_tape(os) : false;
|
||||
}
|
||||
|
||||
inline simdjson_result<size_t> document::parser::read_file(const std::string &path) noexcept {
|
||||
inline simdjson_result<size_t> parser::read_file(const std::string &path) noexcept {
|
||||
// Open the file
|
||||
std::FILE *fp = std::fopen(path.c_str(), "rb");
|
||||
if (fp == nullptr) {
|
||||
|
@ -379,19 +383,19 @@ inline simdjson_result<size_t> document::parser::read_file(const std::string &pa
|
|||
return bytes_read;
|
||||
}
|
||||
|
||||
inline simdjson_result<document::element> document::parser::load(const std::string &path) noexcept {
|
||||
inline simdjson_result<element> parser::load(const std::string &path) noexcept {
|
||||
auto [len, code] = read_file(path);
|
||||
if (code) { return code; }
|
||||
|
||||
return parse(loaded_bytes.get(), len, false);
|
||||
}
|
||||
|
||||
inline document::stream document::parser::load_many(const std::string &path, size_t batch_size) noexcept {
|
||||
inline stream parser::load_many(const std::string &path, size_t batch_size) noexcept {
|
||||
auto [len, code] = read_file(path);
|
||||
return stream(*this, (const uint8_t*)loaded_bytes.get(), len, batch_size, code);
|
||||
}
|
||||
|
||||
inline simdjson_result<document::element> document::parser::parse(const uint8_t *buf, size_t len, bool realloc_if_needed) noexcept {
|
||||
inline simdjson_result<element> parser::parse(const uint8_t *buf, size_t len, bool realloc_if_needed) noexcept {
|
||||
error_code code = ensure_capacity(len);
|
||||
if (code) { return code; }
|
||||
|
||||
|
@ -414,41 +418,41 @@ inline simdjson_result<document::element> document::parser::parse(const uint8_t
|
|||
error = UNINITIALIZED;
|
||||
return doc.root();
|
||||
}
|
||||
really_inline simdjson_result<document::element> document::parser::parse(const char *buf, size_t len, bool realloc_if_needed) noexcept {
|
||||
really_inline simdjson_result<element> parser::parse(const char *buf, size_t len, bool realloc_if_needed) noexcept {
|
||||
return parse((const uint8_t *)buf, len, realloc_if_needed);
|
||||
}
|
||||
really_inline simdjson_result<document::element> document::parser::parse(const std::string &s) noexcept {
|
||||
really_inline simdjson_result<element> parser::parse(const std::string &s) noexcept {
|
||||
return parse(s.data(), s.length(), s.capacity() - s.length() < SIMDJSON_PADDING);
|
||||
}
|
||||
really_inline simdjson_result<document::element> document::parser::parse(const padded_string &s) noexcept {
|
||||
really_inline simdjson_result<element> parser::parse(const padded_string &s) noexcept {
|
||||
return parse(s.data(), s.length(), false);
|
||||
}
|
||||
|
||||
inline document::stream document::parser::parse_many(const uint8_t *buf, size_t len, size_t batch_size) noexcept {
|
||||
inline stream parser::parse_many(const uint8_t *buf, size_t len, size_t batch_size) noexcept {
|
||||
return stream(*this, buf, len, batch_size);
|
||||
}
|
||||
inline document::stream document::parser::parse_many(const char *buf, size_t len, size_t batch_size) noexcept {
|
||||
inline stream parser::parse_many(const char *buf, size_t len, size_t batch_size) noexcept {
|
||||
return parse_many((const uint8_t *)buf, len, batch_size);
|
||||
}
|
||||
inline document::stream document::parser::parse_many(const std::string &s, size_t batch_size) noexcept {
|
||||
inline stream parser::parse_many(const std::string &s, size_t batch_size) noexcept {
|
||||
return parse_many(s.data(), s.length(), batch_size);
|
||||
}
|
||||
inline document::stream document::parser::parse_many(const padded_string &s, size_t batch_size) noexcept {
|
||||
inline stream parser::parse_many(const padded_string &s, size_t batch_size) noexcept {
|
||||
return parse_many(s.data(), s.length(), batch_size);
|
||||
}
|
||||
|
||||
really_inline size_t document::parser::capacity() const noexcept {
|
||||
really_inline size_t parser::capacity() const noexcept {
|
||||
return _capacity;
|
||||
}
|
||||
really_inline size_t document::parser::max_capacity() const noexcept {
|
||||
really_inline size_t parser::max_capacity() const noexcept {
|
||||
return _max_capacity;
|
||||
}
|
||||
really_inline size_t document::parser::max_depth() const noexcept {
|
||||
really_inline size_t parser::max_depth() const noexcept {
|
||||
return _max_depth;
|
||||
}
|
||||
|
||||
WARN_UNUSED
|
||||
inline error_code document::parser::set_capacity(size_t capacity) noexcept {
|
||||
inline error_code parser::set_capacity(size_t capacity) noexcept {
|
||||
if (_capacity == capacity) {
|
||||
return SUCCESS;
|
||||
}
|
||||
|
@ -483,11 +487,11 @@ inline error_code document::parser::set_capacity(size_t capacity) noexcept {
|
|||
return SUCCESS;
|
||||
}
|
||||
|
||||
really_inline void document::parser::set_max_capacity(size_t max_capacity) noexcept {
|
||||
really_inline void parser::set_max_capacity(size_t max_capacity) noexcept {
|
||||
_max_capacity = max_capacity;
|
||||
}
|
||||
|
||||
WARN_UNUSED inline error_code document::parser::set_max_depth(size_t max_depth) noexcept {
|
||||
WARN_UNUSED inline error_code parser::set_max_depth(size_t max_depth) noexcept {
|
||||
if (max_depth == _max_depth && ret_address) { return SUCCESS; }
|
||||
|
||||
_max_depth = 0;
|
||||
|
@ -517,11 +521,11 @@ WARN_UNUSED inline error_code document::parser::set_max_depth(size_t max_depth)
|
|||
return SUCCESS;
|
||||
}
|
||||
|
||||
WARN_UNUSED inline bool document::parser::allocate_capacity(size_t capacity, size_t max_depth) noexcept {
|
||||
WARN_UNUSED inline bool parser::allocate_capacity(size_t capacity, size_t max_depth) noexcept {
|
||||
return !set_capacity(capacity) && !set_max_depth(max_depth);
|
||||
}
|
||||
|
||||
inline error_code document::parser::ensure_capacity(size_t desired_capacity) noexcept {
|
||||
inline error_code parser::ensure_capacity(size_t desired_capacity) noexcept {
|
||||
// If we don't have enough capacity, (try to) automatically bump it.
|
||||
if (unlikely(desired_capacity > capacity())) {
|
||||
if (desired_capacity > max_capacity()) {
|
||||
|
@ -545,59 +549,19 @@ inline error_code document::parser::ensure_capacity(size_t desired_capacity) noe
|
|||
return SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// tape_ref inline implementation
|
||||
//
|
||||
really_inline internal::tape_ref::tape_ref() noexcept : doc{nullptr}, json_index{0} {}
|
||||
really_inline internal::tape_ref::tape_ref(const document *_doc, size_t _json_index) noexcept : doc{_doc}, json_index{_json_index} {}
|
||||
|
||||
inline size_t internal::tape_ref::after_element() const noexcept {
|
||||
switch (type()) {
|
||||
case tape_type::START_ARRAY:
|
||||
case tape_type::START_OBJECT:
|
||||
return tape_value();
|
||||
case tape_type::UINT64:
|
||||
case tape_type::INT64:
|
||||
case tape_type::DOUBLE:
|
||||
return json_index + 2;
|
||||
default:
|
||||
return json_index + 1;
|
||||
}
|
||||
}
|
||||
really_inline internal::tape_type internal::tape_ref::type() const noexcept {
|
||||
return static_cast<tape_type>(doc->tape[json_index] >> 56);
|
||||
}
|
||||
really_inline uint64_t internal::tape_ref::tape_value() const noexcept {
|
||||
return doc->tape[json_index] & internal::JSON_VALUE_MASK;
|
||||
}
|
||||
template<typename T>
|
||||
really_inline T internal::tape_ref::next_tape_value() const noexcept {
|
||||
static_assert(sizeof(T) == sizeof(uint64_t));
|
||||
return *reinterpret_cast<const T*>(&doc->tape[json_index + 1]);
|
||||
}
|
||||
inline std::string_view internal::tape_ref::get_string_view() const noexcept {
|
||||
size_t string_buf_index = tape_value();
|
||||
uint32_t len;
|
||||
memcpy(&len, &doc->string_buf[string_buf_index], sizeof(len));
|
||||
return std::string_view(
|
||||
reinterpret_cast<const char *>(&doc->string_buf[string_buf_index + sizeof(uint32_t)]),
|
||||
len
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// array inline implementation
|
||||
//
|
||||
really_inline document::array::array() noexcept : internal::tape_ref() {}
|
||||
really_inline document::array::array(const document *_doc, size_t _json_index) noexcept : internal::tape_ref(_doc, _json_index) {}
|
||||
inline document::array::iterator document::array::begin() const noexcept {
|
||||
really_inline array::array() noexcept : internal::tape_ref() {}
|
||||
really_inline array::array(const document *_doc, size_t _json_index) noexcept : internal::tape_ref(_doc, _json_index) {}
|
||||
inline array::iterator array::begin() const noexcept {
|
||||
return iterator(doc, json_index + 1);
|
||||
}
|
||||
inline document::array::iterator document::array::end() const noexcept {
|
||||
inline array::iterator array::end() const noexcept {
|
||||
return iterator(doc, after_element() - 1);
|
||||
}
|
||||
|
||||
inline simdjson_result<document::element> document::array::at(const std::string_view &json_pointer) const noexcept {
|
||||
inline simdjson_result<element> array::at(const std::string_view &json_pointer) const noexcept {
|
||||
// - means "the append position" or "the element after the end of the array"
|
||||
// We don't support this, because we're returning a real element, not a position.
|
||||
if (json_pointer == "-") { return INDEX_OUT_OF_BOUNDS; }
|
||||
|
@ -626,7 +590,7 @@ inline simdjson_result<document::element> document::array::at(const std::string_
|
|||
}
|
||||
return child;
|
||||
}
|
||||
inline simdjson_result<document::element> document::array::at(size_t index) const noexcept {
|
||||
inline simdjson_result<element> array::at(size_t index) const noexcept {
|
||||
size_t i=0;
|
||||
for (auto element : *this) {
|
||||
if (i == index) { return element; }
|
||||
|
@ -636,43 +600,43 @@ inline simdjson_result<document::element> document::array::at(size_t index) cons
|
|||
}
|
||||
|
||||
//
|
||||
// document::array::iterator inline implementation
|
||||
// array::iterator inline implementation
|
||||
//
|
||||
really_inline document::array::iterator::iterator(const document *_doc, size_t _json_index) noexcept : internal::tape_ref(_doc, _json_index) { }
|
||||
inline document::element document::array::iterator::operator*() const noexcept {
|
||||
really_inline array::iterator::iterator(const document *_doc, size_t _json_index) noexcept : internal::tape_ref(_doc, _json_index) { }
|
||||
inline element array::iterator::operator*() const noexcept {
|
||||
return element(doc, json_index);
|
||||
}
|
||||
inline bool document::array::iterator::operator!=(const document::array::iterator& other) const noexcept {
|
||||
inline bool array::iterator::operator!=(const array::iterator& other) const noexcept {
|
||||
return json_index != other.json_index;
|
||||
}
|
||||
inline void document::array::iterator::operator++() noexcept {
|
||||
inline void array::iterator::operator++() noexcept {
|
||||
json_index = after_element();
|
||||
}
|
||||
|
||||
//
|
||||
// document::object inline implementation
|
||||
// object inline implementation
|
||||
//
|
||||
really_inline document::object::object() noexcept : internal::tape_ref() {}
|
||||
really_inline document::object::object(const document *_doc, size_t _json_index) noexcept : internal::tape_ref(_doc, _json_index) { };
|
||||
inline document::object::iterator document::object::begin() const noexcept {
|
||||
really_inline object::object() noexcept : internal::tape_ref() {}
|
||||
really_inline object::object(const document *_doc, size_t _json_index) noexcept : internal::tape_ref(_doc, _json_index) { };
|
||||
inline object::iterator object::begin() const noexcept {
|
||||
return iterator(doc, json_index + 1);
|
||||
}
|
||||
inline document::object::iterator document::object::end() const noexcept {
|
||||
inline object::iterator object::end() const noexcept {
|
||||
return iterator(doc, after_element() - 1);
|
||||
}
|
||||
|
||||
inline simdjson_result<document::element> document::object::operator[](const std::string_view &json_pointer) const noexcept {
|
||||
inline simdjson_result<element> object::operator[](const std::string_view &json_pointer) const noexcept {
|
||||
return at(json_pointer);
|
||||
}
|
||||
inline simdjson_result<document::element> document::object::operator[](const char *json_pointer) const noexcept {
|
||||
inline simdjson_result<element> object::operator[](const char *json_pointer) const noexcept {
|
||||
return at(json_pointer);
|
||||
}
|
||||
inline simdjson_result<document::element> document::object::at(const std::string_view &json_pointer) const noexcept {
|
||||
inline simdjson_result<element> object::at(const std::string_view &json_pointer) const noexcept {
|
||||
size_t slash = json_pointer.find('/');
|
||||
std::string_view key = json_pointer.substr(0, slash);
|
||||
|
||||
// Grab the child with the given key
|
||||
simdjson_result<document::element> child;
|
||||
simdjson_result<element> child;
|
||||
|
||||
// If there is an escape character in the key, unescape it and then get the child.
|
||||
size_t escape = key.find('~');
|
||||
|
@ -704,7 +668,7 @@ inline simdjson_result<document::element> document::object::at(const std::string
|
|||
|
||||
return child;
|
||||
}
|
||||
inline simdjson_result<document::element> document::object::at_key(const std::string_view &key) const noexcept {
|
||||
inline simdjson_result<element> object::at_key(const std::string_view &key) const noexcept {
|
||||
iterator end_field = end();
|
||||
for (iterator field = begin(); field != end_field; ++field) {
|
||||
if (key == field.key()) {
|
||||
|
@ -716,7 +680,7 @@ inline simdjson_result<document::element> document::object::at_key(const std::st
|
|||
// In case you wonder why we need this, please see
|
||||
// https://github.com/simdjson/simdjson/issues/323
|
||||
// People do seek keys in a case-insensitive manner.
|
||||
inline simdjson_result<document::element> document::object::at_key_case_insensitive(const std::string_view &key) const noexcept {
|
||||
inline simdjson_result<element> object::at_key_case_insensitive(const std::string_view &key) const noexcept {
|
||||
iterator end_field = end();
|
||||
for (iterator field = begin(); field != end_field; ++field) {
|
||||
auto field_key = field.key();
|
||||
|
@ -732,20 +696,20 @@ inline simdjson_result<document::element> document::object::at_key_case_insensit
|
|||
}
|
||||
|
||||
//
|
||||
// document::object::iterator inline implementation
|
||||
// object::iterator inline implementation
|
||||
//
|
||||
really_inline document::object::iterator::iterator(const document *_doc, size_t _json_index) noexcept : internal::tape_ref(_doc, _json_index) { }
|
||||
inline const document::key_value_pair document::object::iterator::operator*() const noexcept {
|
||||
really_inline object::iterator::iterator(const document *_doc, size_t _json_index) noexcept : internal::tape_ref(_doc, _json_index) { }
|
||||
inline const key_value_pair object::iterator::operator*() const noexcept {
|
||||
return key_value_pair(key(), value());
|
||||
}
|
||||
inline bool document::object::iterator::operator!=(const document::object::iterator& other) const noexcept {
|
||||
inline bool object::iterator::operator!=(const object::iterator& other) const noexcept {
|
||||
return json_index != other.json_index;
|
||||
}
|
||||
inline void document::object::iterator::operator++() noexcept {
|
||||
inline void object::iterator::operator++() noexcept {
|
||||
json_index++;
|
||||
json_index = after_element();
|
||||
}
|
||||
inline std::string_view document::object::iterator::key() const noexcept {
|
||||
inline std::string_view object::iterator::key() const noexcept {
|
||||
size_t string_buf_index = tape_value();
|
||||
uint32_t len;
|
||||
memcpy(&len, &doc->string_buf[string_buf_index], sizeof(len));
|
||||
|
@ -754,67 +718,67 @@ inline std::string_view document::object::iterator::key() const noexcept {
|
|||
len
|
||||
);
|
||||
}
|
||||
inline const char* document::object::iterator::key_c_str() const noexcept {
|
||||
inline const char* object::iterator::key_c_str() const noexcept {
|
||||
return reinterpret_cast<const char *>(&doc->string_buf[tape_value() + sizeof(uint32_t)]);
|
||||
}
|
||||
inline document::element document::object::iterator::value() const noexcept {
|
||||
inline element object::iterator::value() const noexcept {
|
||||
return element(doc, json_index + 1);
|
||||
}
|
||||
|
||||
//
|
||||
// document::key_value_pair inline implementation
|
||||
// key_value_pair inline implementation
|
||||
//
|
||||
inline document::key_value_pair::key_value_pair(const std::string_view &_key, element _value) noexcept :
|
||||
inline key_value_pair::key_value_pair(const std::string_view &_key, element _value) noexcept :
|
||||
key(_key), value(_value) {}
|
||||
|
||||
//
|
||||
// element inline implementation
|
||||
//
|
||||
really_inline document::element::element() noexcept : internal::tape_ref() {}
|
||||
really_inline document::element::element(const document *_doc, size_t _json_index) noexcept : internal::tape_ref(_doc, _json_index) { }
|
||||
really_inline element::element() noexcept : internal::tape_ref() {}
|
||||
really_inline element::element(const document *_doc, size_t _json_index) noexcept : internal::tape_ref(_doc, _json_index) { }
|
||||
|
||||
really_inline bool document::element::is_null() const noexcept {
|
||||
really_inline bool element::is_null() const noexcept {
|
||||
return type() == internal::tape_type::NULL_VALUE;
|
||||
}
|
||||
really_inline bool document::element::is_bool() const noexcept {
|
||||
really_inline bool element::is_bool() const noexcept {
|
||||
return type() == internal::tape_type::TRUE_VALUE || type() == internal::tape_type::FALSE_VALUE;
|
||||
}
|
||||
really_inline bool document::element::is_number() const noexcept {
|
||||
really_inline bool element::is_number() const noexcept {
|
||||
return type() == internal::tape_type::UINT64 || type() == internal::tape_type::INT64 || type() == internal::tape_type::DOUBLE;
|
||||
}
|
||||
really_inline bool document::element::is_float() const noexcept {
|
||||
really_inline bool element::is_float() const noexcept {
|
||||
return type() == internal::tape_type::DOUBLE;
|
||||
}
|
||||
really_inline bool document::element::is_integer() const noexcept {
|
||||
really_inline bool element::is_integer() const noexcept {
|
||||
return type() == internal::tape_type::UINT64 || type() == internal::tape_type::INT64;
|
||||
}
|
||||
really_inline bool document::element::is_unsigned_integer() const noexcept {
|
||||
really_inline bool element::is_unsigned_integer() const noexcept {
|
||||
return type() == internal::tape_type::UINT64;
|
||||
}
|
||||
really_inline bool document::element::is_string() const noexcept {
|
||||
really_inline bool element::is_string() const noexcept {
|
||||
return type() == internal::tape_type::STRING;
|
||||
}
|
||||
really_inline bool document::element::is_array() const noexcept {
|
||||
really_inline bool element::is_array() const noexcept {
|
||||
return type() == internal::tape_type::START_ARRAY;
|
||||
}
|
||||
really_inline bool document::element::is_object() const noexcept {
|
||||
really_inline bool element::is_object() const noexcept {
|
||||
return type() == internal::tape_type::START_OBJECT;
|
||||
}
|
||||
|
||||
#if SIMDJSON_EXCEPTIONS
|
||||
|
||||
inline document::element::operator bool() const noexcept(false) { return as_bool(); }
|
||||
inline document::element::operator const char*() const noexcept(false) { return as_c_str(); }
|
||||
inline document::element::operator std::string_view() const noexcept(false) { return as_string(); }
|
||||
inline document::element::operator uint64_t() const noexcept(false) { return as_uint64_t(); }
|
||||
inline document::element::operator int64_t() const noexcept(false) { return as_int64_t(); }
|
||||
inline document::element::operator double() const noexcept(false) { return as_double(); }
|
||||
inline document::element::operator document::array() const noexcept(false) { return as_array(); }
|
||||
inline document::element::operator document::object() const noexcept(false) { return as_object(); }
|
||||
inline element::operator bool() const noexcept(false) { return as_bool(); }
|
||||
inline element::operator const char*() const noexcept(false) { return as_c_str(); }
|
||||
inline element::operator std::string_view() const noexcept(false) { return as_string(); }
|
||||
inline element::operator uint64_t() const noexcept(false) { return as_uint64_t(); }
|
||||
inline element::operator int64_t() const noexcept(false) { return as_int64_t(); }
|
||||
inline element::operator double() const noexcept(false) { return as_double(); }
|
||||
inline element::operator array() const noexcept(false) { return as_array(); }
|
||||
inline element::operator object() const noexcept(false) { return as_object(); }
|
||||
|
||||
#endif
|
||||
|
||||
inline simdjson_result<bool> document::element::as_bool() const noexcept {
|
||||
inline simdjson_result<bool> element::as_bool() const noexcept {
|
||||
switch (type()) {
|
||||
case internal::tape_type::TRUE_VALUE:
|
||||
return true;
|
||||
|
@ -824,7 +788,7 @@ inline simdjson_result<bool> document::element::as_bool() const noexcept {
|
|||
return INCORRECT_TYPE;
|
||||
}
|
||||
}
|
||||
inline simdjson_result<const char *> document::element::as_c_str() const noexcept {
|
||||
inline simdjson_result<const char *> element::as_c_str() const noexcept {
|
||||
switch (type()) {
|
||||
case internal::tape_type::STRING: {
|
||||
size_t string_buf_index = tape_value();
|
||||
|
@ -834,7 +798,7 @@ inline simdjson_result<const char *> document::element::as_c_str() const noexcep
|
|||
return INCORRECT_TYPE;
|
||||
}
|
||||
}
|
||||
inline simdjson_result<std::string_view> document::element::as_string() const noexcept {
|
||||
inline simdjson_result<std::string_view> element::as_string() const noexcept {
|
||||
switch (type()) {
|
||||
case internal::tape_type::STRING:
|
||||
return get_string_view();
|
||||
|
@ -842,7 +806,7 @@ inline simdjson_result<std::string_view> document::element::as_string() const no
|
|||
return INCORRECT_TYPE;
|
||||
}
|
||||
}
|
||||
inline simdjson_result<uint64_t> document::element::as_uint64_t() const noexcept {
|
||||
inline simdjson_result<uint64_t> element::as_uint64_t() const noexcept {
|
||||
switch (type()) {
|
||||
case internal::tape_type::UINT64:
|
||||
return next_tape_value<uint64_t>();
|
||||
|
@ -857,7 +821,7 @@ inline simdjson_result<uint64_t> document::element::as_uint64_t() const noexcept
|
|||
return INCORRECT_TYPE;
|
||||
}
|
||||
}
|
||||
inline simdjson_result<int64_t> document::element::as_int64_t() const noexcept {
|
||||
inline simdjson_result<int64_t> element::as_int64_t() const noexcept {
|
||||
switch (type()) {
|
||||
case internal::tape_type::UINT64: {
|
||||
uint64_t result = next_tape_value<uint64_t>();
|
||||
|
@ -873,7 +837,7 @@ inline simdjson_result<int64_t> document::element::as_int64_t() const noexcept {
|
|||
return INCORRECT_TYPE;
|
||||
}
|
||||
}
|
||||
inline simdjson_result<double> document::element::as_double() const noexcept {
|
||||
inline simdjson_result<double> element::as_double() const noexcept {
|
||||
switch (type()) {
|
||||
case internal::tape_type::UINT64:
|
||||
return next_tape_value<uint64_t>();
|
||||
|
@ -891,7 +855,7 @@ inline simdjson_result<double> document::element::as_double() const noexcept {
|
|||
return INCORRECT_TYPE;
|
||||
}
|
||||
}
|
||||
inline simdjson_result<document::array> document::element::as_array() const noexcept {
|
||||
inline simdjson_result<array> element::as_array() const noexcept {
|
||||
switch (type()) {
|
||||
case internal::tape_type::START_ARRAY:
|
||||
return array(doc, json_index);
|
||||
|
@ -899,7 +863,7 @@ inline simdjson_result<document::array> document::element::as_array() const noex
|
|||
return INCORRECT_TYPE;
|
||||
}
|
||||
}
|
||||
inline simdjson_result<document::object> document::element::as_object() const noexcept {
|
||||
inline simdjson_result<object> element::as_object() const noexcept {
|
||||
switch (type()) {
|
||||
case internal::tape_type::START_OBJECT:
|
||||
return object(doc, json_index);
|
||||
|
@ -907,13 +871,13 @@ inline simdjson_result<document::object> document::element::as_object() const no
|
|||
return INCORRECT_TYPE;
|
||||
}
|
||||
}
|
||||
inline simdjson_result<document::element> document::element::operator[](const std::string_view &json_pointer) const noexcept {
|
||||
inline simdjson_result<element> element::operator[](const std::string_view &json_pointer) const noexcept {
|
||||
return at(json_pointer);
|
||||
}
|
||||
inline simdjson_result<document::element> document::element::operator[](const char *json_pointer) const noexcept {
|
||||
inline simdjson_result<element> element::operator[](const char *json_pointer) const noexcept {
|
||||
return at(json_pointer);
|
||||
}
|
||||
inline simdjson_result<document::element> document::element::at(const std::string_view &json_pointer) const noexcept {
|
||||
inline simdjson_result<element> element::at(const std::string_view &json_pointer) const noexcept {
|
||||
switch (type()) {
|
||||
case internal::tape_type::START_OBJECT:
|
||||
return object(doc, json_index).at(json_pointer);
|
||||
|
@ -923,26 +887,30 @@ inline simdjson_result<document::element> document::element::at(const std::strin
|
|||
return INCORRECT_TYPE;
|
||||
}
|
||||
}
|
||||
inline simdjson_result<document::element> document::element::at(size_t index) const noexcept {
|
||||
inline simdjson_result<element> element::at(size_t index) const noexcept {
|
||||
return as_array().at(index);
|
||||
}
|
||||
inline simdjson_result<document::element> document::element::at_key(const std::string_view &key) const noexcept {
|
||||
inline simdjson_result<element> element::at_key(const std::string_view &key) const noexcept {
|
||||
return as_object().at_key(key);
|
||||
}
|
||||
inline simdjson_result<document::element> document::element::at_key_case_insensitive(const std::string_view &key) const noexcept {
|
||||
inline simdjson_result<element> element::at_key_case_insensitive(const std::string_view &key) const noexcept {
|
||||
return as_object().at_key_case_insensitive(key);
|
||||
}
|
||||
|
||||
inline bool document::element::dump_raw_tape(std::ostream &out) const noexcept {
|
||||
inline bool element::dump_raw_tape(std::ostream &out) const noexcept {
|
||||
return doc->dump_raw_tape(out);
|
||||
}
|
||||
|
||||
} // namespace simdjson::dom
|
||||
|
||||
namespace simdjson {
|
||||
|
||||
//
|
||||
// minify inline implementation
|
||||
//
|
||||
|
||||
template<>
|
||||
inline std::ostream& minify<document::element>::print(std::ostream& out) {
|
||||
inline std::ostream& minify<dom::element>::print(std::ostream& out) {
|
||||
using tape_type=internal::tape_type;
|
||||
size_t depth = 0;
|
||||
constexpr size_t MAX_DEPTH = 16;
|
||||
|
@ -950,7 +918,7 @@ inline std::ostream& minify<document::element>::print(std::ostream& out) {
|
|||
is_object[0] = false;
|
||||
bool after_value = false;
|
||||
|
||||
internal::tape_ref iter(value.doc, value.json_index);
|
||||
internal::tape_ref iter(value);
|
||||
do {
|
||||
// print commas after each value
|
||||
if (after_value) {
|
||||
|
@ -968,7 +936,7 @@ inline std::ostream& minify<document::element>::print(std::ostream& out) {
|
|||
// If we're too deep, we need to recurse to go deeper.
|
||||
depth++;
|
||||
if (unlikely(depth >= MAX_DEPTH)) {
|
||||
out << minify<document::array>(document::array(iter.doc, iter.json_index));
|
||||
out << minify<dom::array>(dom::array(iter.doc, iter.json_index));
|
||||
iter.json_index = iter.tape_value() - 1; // Jump to the ]
|
||||
depth--;
|
||||
break;
|
||||
|
@ -995,7 +963,7 @@ inline std::ostream& minify<document::element>::print(std::ostream& out) {
|
|||
// If we're too deep, we need to recurse to go deeper.
|
||||
depth++;
|
||||
if (unlikely(depth >= MAX_DEPTH)) {
|
||||
out << minify<document::object>(document::object(iter.doc, iter.json_index));
|
||||
out << minify<dom::object>(dom::object(iter.doc, iter.json_index));
|
||||
iter.json_index = iter.tape_value() - 1; // Jump to the }
|
||||
depth--;
|
||||
break;
|
||||
|
@ -1065,56 +1033,101 @@ inline std::ostream& minify<document::element>::print(std::ostream& out) {
|
|||
return out;
|
||||
}
|
||||
template<>
|
||||
inline std::ostream& minify<document::object>::print(std::ostream& out) {
|
||||
inline std::ostream& minify<dom::object>::print(std::ostream& out) {
|
||||
out << '{';
|
||||
auto pair = value.begin();
|
||||
auto end = value.end();
|
||||
if (pair != end) {
|
||||
out << minify<document::key_value_pair>(*pair);
|
||||
out << minify<dom::key_value_pair>(*pair);
|
||||
for (++pair; pair != end; ++pair) {
|
||||
out << "," << minify<document::key_value_pair>(*pair);
|
||||
out << "," << minify<dom::key_value_pair>(*pair);
|
||||
}
|
||||
}
|
||||
return out << '}';
|
||||
}
|
||||
template<>
|
||||
inline std::ostream& minify<document::array>::print(std::ostream& out) {
|
||||
inline std::ostream& minify<dom::array>::print(std::ostream& out) {
|
||||
out << '[';
|
||||
auto element = value.begin();
|
||||
auto iter = value.begin();
|
||||
auto end = value.end();
|
||||
if (element != end) {
|
||||
out << minify<document::element>(*element);
|
||||
for (++element; element != end; ++element) {
|
||||
out << "," << minify<document::element>(*element);
|
||||
if (iter != end) {
|
||||
out << minify<dom::element>(*iter);
|
||||
for (++iter; iter != end; ++iter) {
|
||||
out << "," << minify<dom::element>(*iter);
|
||||
}
|
||||
}
|
||||
return out << ']';
|
||||
}
|
||||
template<>
|
||||
inline std::ostream& minify<document::key_value_pair>::print(std::ostream& out) {
|
||||
inline std::ostream& minify<dom::key_value_pair>::print(std::ostream& out) {
|
||||
return out << '"' << internal::escape_json_string(value.key) << "\":" << value.value;
|
||||
}
|
||||
|
||||
#if SIMDJSON_EXCEPTIONS
|
||||
|
||||
template<>
|
||||
inline std::ostream& minify<simdjson_result<document::element>>::print(std::ostream& out) {
|
||||
inline std::ostream& minify<simdjson_result<dom::element>>::print(std::ostream& out) {
|
||||
if (value.error()) { throw simdjson_error(value.error()); }
|
||||
return out << minify<document::element>(value.first);
|
||||
return out << minify<dom::element>(value.first);
|
||||
}
|
||||
template<>
|
||||
inline std::ostream& minify<simdjson_result<document::array>>::print(std::ostream& out) {
|
||||
inline std::ostream& minify<simdjson_result<dom::array>>::print(std::ostream& out) {
|
||||
if (value.error()) { throw simdjson_error(value.error()); }
|
||||
return out << minify<document::array>(value.first);
|
||||
return out << minify<dom::array>(value.first);
|
||||
}
|
||||
template<>
|
||||
inline std::ostream& minify<simdjson_result<document::object>>::print(std::ostream& out) {
|
||||
inline std::ostream& minify<simdjson_result<dom::object>>::print(std::ostream& out) {
|
||||
if (value.error()) { throw simdjson_error(value.error()); }
|
||||
return out << minify<document::object>(value.first);
|
||||
return out << minify<dom::object>(value.first);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace simdjson
|
||||
|
||||
namespace simdjson::internal {
|
||||
|
||||
//
|
||||
// tape_ref inline implementation
|
||||
//
|
||||
really_inline tape_ref::tape_ref() noexcept : doc{nullptr}, json_index{0} {}
|
||||
really_inline tape_ref::tape_ref(const document *_doc, size_t _json_index) noexcept : doc{_doc}, json_index{_json_index} {}
|
||||
|
||||
inline size_t tape_ref::after_element() const noexcept {
|
||||
switch (type()) {
|
||||
case tape_type::START_ARRAY:
|
||||
case tape_type::START_OBJECT:
|
||||
return tape_value();
|
||||
case tape_type::UINT64:
|
||||
case tape_type::INT64:
|
||||
case tape_type::DOUBLE:
|
||||
return json_index + 2;
|
||||
default:
|
||||
return json_index + 1;
|
||||
}
|
||||
}
|
||||
really_inline tape_type tape_ref::type() const noexcept {
|
||||
return static_cast<tape_type>(doc->tape[json_index] >> 56);
|
||||
}
|
||||
really_inline uint64_t internal::tape_ref::tape_value() const noexcept {
|
||||
return doc->tape[json_index] & internal::JSON_VALUE_MASK;
|
||||
}
|
||||
template<typename T>
|
||||
really_inline T tape_ref::next_tape_value() const noexcept {
|
||||
static_assert(sizeof(T) == sizeof(uint64_t));
|
||||
return *reinterpret_cast<const T*>(&doc->tape[json_index + 1]);
|
||||
}
|
||||
inline std::string_view internal::tape_ref::get_string_view() const noexcept {
|
||||
size_t string_buf_index = tape_value();
|
||||
uint32_t len;
|
||||
memcpy(&len, &doc->string_buf[string_buf_index], sizeof(len));
|
||||
return std::string_view(
|
||||
reinterpret_cast<const char *>(&doc->string_buf[string_buf_index + sizeof(uint32_t)]),
|
||||
len
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
} // namespace simdjson::internal
|
||||
|
||||
#endif // SIMDJSON_INLINE_DOCUMENT_H
|
||||
|
|
|
@ -32,7 +32,7 @@ namespace simdjson::internal {
|
|||
* complete
|
||||
* document, therefore the last json buffer location is the end of the batch
|
||||
* */
|
||||
inline size_t find_last_json_buf_idx(const uint8_t *buf, size_t size, const document::parser &parser) {
|
||||
inline size_t find_last_json_buf_idx(const uint8_t *buf, size_t size, const dom::parser &parser) {
|
||||
// this function can be generally useful
|
||||
if (parser.n_structural_indexes == 0)
|
||||
return 0;
|
||||
|
@ -95,10 +95,10 @@ static inline size_t trimmed_length_safe_utf8(const char * c, size_t len) {
|
|||
|
||||
} // namespace simdjson::internal
|
||||
|
||||
namespace simdjson {
|
||||
namespace simdjson::dom {
|
||||
|
||||
really_inline document::stream::stream(
|
||||
document::parser &_parser,
|
||||
really_inline stream::stream(
|
||||
dom::parser &_parser,
|
||||
const uint8_t *buf,
|
||||
size_t len,
|
||||
size_t batch_size,
|
||||
|
@ -107,7 +107,7 @@ really_inline document::stream::stream(
|
|||
if (!error) { error = json_parse(); }
|
||||
}
|
||||
|
||||
inline document::stream::~stream() noexcept {
|
||||
inline stream::~stream() noexcept {
|
||||
#ifdef SIMDJSON_THREADS_ENABLED
|
||||
if (stage_1_thread.joinable()) {
|
||||
stage_1_thread.join();
|
||||
|
@ -115,25 +115,25 @@ inline document::stream::~stream() noexcept {
|
|||
#endif
|
||||
}
|
||||
|
||||
really_inline document::stream::iterator document::stream::begin() noexcept {
|
||||
really_inline stream::iterator stream::begin() noexcept {
|
||||
return iterator(*this, false);
|
||||
}
|
||||
|
||||
really_inline document::stream::iterator document::stream::end() noexcept {
|
||||
really_inline stream::iterator stream::end() noexcept {
|
||||
return iterator(*this, true);
|
||||
}
|
||||
|
||||
really_inline document::stream::iterator::iterator(stream& stream, bool _is_end) noexcept
|
||||
really_inline stream::iterator::iterator(stream& stream, bool _is_end) noexcept
|
||||
: _stream{stream}, finished{_is_end} {
|
||||
}
|
||||
|
||||
really_inline simdjson_result<document::element> document::stream::iterator::operator*() noexcept {
|
||||
really_inline simdjson_result<element> stream::iterator::operator*() noexcept {
|
||||
error_code error = _stream.error == SUCCESS_AND_HAS_MORE ? SUCCESS : _stream.error;
|
||||
if (error) { return error; }
|
||||
return _stream.parser.doc.root();
|
||||
}
|
||||
|
||||
really_inline document::stream::iterator& document::stream::iterator::operator++() noexcept {
|
||||
really_inline stream::iterator& stream::iterator::operator++() noexcept {
|
||||
if (_stream.error == SUCCESS_AND_HAS_MORE) {
|
||||
_stream.error = _stream.json_parse();
|
||||
} else {
|
||||
|
@ -142,7 +142,7 @@ really_inline document::stream::iterator& document::stream::iterator::operator++
|
|||
return *this;
|
||||
}
|
||||
|
||||
really_inline bool document::stream::iterator::operator!=(const document::stream::iterator &other) const noexcept {
|
||||
really_inline bool stream::iterator::operator!=(const stream::iterator &other) const noexcept {
|
||||
return finished != other.finished;
|
||||
}
|
||||
|
||||
|
@ -150,7 +150,7 @@ really_inline bool document::stream::iterator::operator!=(const document::stream
|
|||
|
||||
// threaded version of json_parse
|
||||
// todo: simplify this code further
|
||||
inline error_code document::stream::json_parse() noexcept {
|
||||
inline error_code stream::json_parse() noexcept {
|
||||
error = parser.ensure_capacity(_batch_size);
|
||||
if (error) { return error; }
|
||||
error = parser_thread.ensure_capacity(_batch_size);
|
||||
|
@ -232,7 +232,7 @@ inline error_code document::stream::json_parse() noexcept {
|
|||
#else // SIMDJSON_THREADS_ENABLED
|
||||
|
||||
// single-threaded version of json_parse
|
||||
inline error_code document::stream::json_parse() noexcept {
|
||||
inline error_code stream::json_parse() noexcept {
|
||||
error = parser.ensure_capacity(_batch_size);
|
||||
if (error) { return error; }
|
||||
|
||||
|
@ -272,5 +272,5 @@ inline error_code document::stream::json_parse() noexcept {
|
|||
}
|
||||
#endif // SIMDJSON_THREADS_ENABLED
|
||||
|
||||
} // end of namespace simdjson
|
||||
} // namespace simdjson::dom
|
||||
#endif // SIMDJSON_INLINE_DOCUMENT_STREAM_H
|
||||
|
|
|
@ -13,8 +13,8 @@ namespace simdjson {
|
|||
// C API (json_parse and build_parsed_json) declarations
|
||||
//
|
||||
|
||||
[[deprecated("Use document::parser.parse() instead")]]
|
||||
inline int json_parse(const uint8_t *buf, size_t len, document::parser &parser, bool realloc_if_needed = true) noexcept {
|
||||
[[deprecated("Use parser.parse() instead")]]
|
||||
inline int json_parse(const uint8_t *buf, size_t len, dom::parser &parser, bool realloc_if_needed = true) noexcept {
|
||||
error_code code = parser.parse(buf, len, realloc_if_needed).error();
|
||||
// The deprecated json_parse API is a signal that the user plans to *use* the error code / valid
|
||||
// bits in the parser instead of heeding the result code. The normal parser unsets those in
|
||||
|
@ -24,8 +24,8 @@ inline int json_parse(const uint8_t *buf, size_t len, document::parser &parser,
|
|||
parser.error = code;
|
||||
return code;
|
||||
}
|
||||
[[deprecated("Use document::parser.parse() instead")]]
|
||||
inline int json_parse(const char *buf, size_t len, document::parser &parser, bool realloc_if_needed = true) noexcept {
|
||||
[[deprecated("Use parser.parse() instead")]]
|
||||
inline int json_parse(const char *buf, size_t len, dom::parser &parser, bool realloc_if_needed = true) noexcept {
|
||||
error_code code = parser.parse(buf, len, realloc_if_needed).error();
|
||||
// The deprecated json_parse API is a signal that the user plans to *use* the error code / valid
|
||||
// bits in the parser instead of heeding the result code. The normal parser unsets those in
|
||||
|
@ -35,8 +35,8 @@ inline int json_parse(const char *buf, size_t len, document::parser &parser, boo
|
|||
parser.error = code;
|
||||
return code;
|
||||
}
|
||||
[[deprecated("Use document::parser.parse() instead")]]
|
||||
inline int json_parse(const std::string &s, document::parser &parser, bool realloc_if_needed = true) noexcept {
|
||||
[[deprecated("Use parser.parse() instead")]]
|
||||
inline int json_parse(const std::string &s, dom::parser &parser, bool realloc_if_needed = true) noexcept {
|
||||
error_code code = parser.parse(s.data(), s.length(), realloc_if_needed).error();
|
||||
// The deprecated json_parse API is a signal that the user plans to *use* the error code / valid
|
||||
// bits in the parser instead of heeding the result code. The normal parser unsets those in
|
||||
|
@ -46,8 +46,8 @@ inline int json_parse(const std::string &s, document::parser &parser, bool reall
|
|||
parser.error = code;
|
||||
return code;
|
||||
}
|
||||
[[deprecated("Use document::parser.parse() instead")]]
|
||||
inline int json_parse(const padded_string &s, document::parser &parser) noexcept {
|
||||
[[deprecated("Use parser.parse() instead")]]
|
||||
inline int json_parse(const padded_string &s, dom::parser &parser) noexcept {
|
||||
error_code code = parser.parse(s).error();
|
||||
// The deprecated json_parse API is a signal that the user plans to *use* the error code / valid
|
||||
// bits in the parser instead of heeding the result code. The normal parser unsets those in
|
||||
|
@ -58,9 +58,9 @@ inline int json_parse(const padded_string &s, document::parser &parser) noexcept
|
|||
return code;
|
||||
}
|
||||
|
||||
[[deprecated("Use document::parser.parse() instead")]]
|
||||
WARN_UNUSED inline document::parser build_parsed_json(const uint8_t *buf, size_t len, bool realloc_if_needed = true) noexcept {
|
||||
document::parser parser;
|
||||
[[deprecated("Use parser.parse() instead")]]
|
||||
WARN_UNUSED inline dom::parser build_parsed_json(const uint8_t *buf, size_t len, bool realloc_if_needed = true) noexcept {
|
||||
dom::parser parser;
|
||||
error_code code = parser.parse(buf, len, realloc_if_needed).error();
|
||||
// The deprecated json_parse API is a signal that the user plans to *use* the error code / valid
|
||||
// bits in the parser instead of heeding the result code. The normal parser unsets those in
|
||||
|
@ -70,9 +70,9 @@ WARN_UNUSED inline document::parser build_parsed_json(const uint8_t *buf, size_t
|
|||
parser.error = code;
|
||||
return parser;
|
||||
}
|
||||
[[deprecated("Use document::parser.parse() instead")]]
|
||||
WARN_UNUSED inline document::parser build_parsed_json(const char *buf, size_t len, bool realloc_if_needed = true) noexcept {
|
||||
document::parser parser;
|
||||
[[deprecated("Use parser.parse() instead")]]
|
||||
WARN_UNUSED inline dom::parser build_parsed_json(const char *buf, size_t len, bool realloc_if_needed = true) noexcept {
|
||||
dom::parser parser;
|
||||
error_code code = parser.parse(buf, len, realloc_if_needed).error();
|
||||
// The deprecated json_parse API is a signal that the user plans to *use* the error code / valid
|
||||
// bits in the parser instead of heeding the result code. The normal parser unsets those in
|
||||
|
@ -82,9 +82,9 @@ WARN_UNUSED inline document::parser build_parsed_json(const char *buf, size_t le
|
|||
parser.error = code;
|
||||
return parser;
|
||||
}
|
||||
[[deprecated("Use document::parser.parse() instead")]]
|
||||
WARN_UNUSED inline document::parser build_parsed_json(const std::string &s, bool realloc_if_needed = true) noexcept {
|
||||
document::parser parser;
|
||||
[[deprecated("Use parser.parse() instead")]]
|
||||
WARN_UNUSED inline dom::parser build_parsed_json(const std::string &s, bool realloc_if_needed = true) noexcept {
|
||||
dom::parser parser;
|
||||
error_code code = parser.parse(s.data(), s.length(), realloc_if_needed).error();
|
||||
// The deprecated json_parse API is a signal that the user plans to *use* the error code / valid
|
||||
// bits in the parser instead of heeding the result code. The normal parser unsets those in
|
||||
|
@ -94,9 +94,9 @@ WARN_UNUSED inline document::parser build_parsed_json(const std::string &s, bool
|
|||
parser.error = code;
|
||||
return parser;
|
||||
}
|
||||
[[deprecated("Use document::parser.parse() instead")]]
|
||||
WARN_UNUSED inline document::parser build_parsed_json(const padded_string &s) noexcept {
|
||||
document::parser parser;
|
||||
[[deprecated("Use parser.parse() instead")]]
|
||||
WARN_UNUSED inline dom::parser build_parsed_json(const padded_string &s) noexcept {
|
||||
dom::parser parser;
|
||||
error_code code = parser.parse(s).error();
|
||||
// The deprecated json_parse API is a signal that the user plans to *use* the error code / valid
|
||||
// bits in the parser instead of heeding the result code. The normal parser unsets those in
|
||||
|
@ -108,8 +108,8 @@ WARN_UNUSED inline document::parser build_parsed_json(const padded_string &s) no
|
|||
}
|
||||
|
||||
// We do not want to allow implicit conversion from C string to std::string.
|
||||
int json_parse(const char *buf, document::parser &parser) noexcept = delete;
|
||||
document::parser build_parsed_json(const char *buf) noexcept = delete;
|
||||
int json_parse(const char *buf, dom::parser &parser) noexcept = delete;
|
||||
dom::parser build_parsed_json(const char *buf) noexcept = delete;
|
||||
|
||||
} // namespace simdjson
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
namespace simdjson {
|
||||
|
||||
/**
|
||||
* String with extra allocation for ease of use with document::parser::parse()
|
||||
* String with extra allocation for ease of use with parser::parse()
|
||||
*
|
||||
* This is a move-only class, it cannot be copied.
|
||||
*/
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace simdjson {
|
||||
|
||||
using ParsedJson = document::parser;
|
||||
using ParsedJson = dom::parser;
|
||||
|
||||
} // namespace simdjson
|
||||
#endif
|
||||
|
|
|
@ -6,14 +6,16 @@
|
|||
|
||||
namespace simdjson::arm64 {
|
||||
|
||||
using namespace simdjson::dom;
|
||||
|
||||
class implementation final : public simdjson::implementation {
|
||||
public:
|
||||
really_inline implementation() : simdjson::implementation("arm64", "ARM NEON", instruction_set::NEON) {}
|
||||
WARN_UNUSED error_code parse(const uint8_t *buf, size_t len, document::parser &parser) const noexcept final;
|
||||
WARN_UNUSED error_code parse(const uint8_t *buf, size_t len, parser &parser) const noexcept final;
|
||||
WARN_UNUSED error_code minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept final;
|
||||
WARN_UNUSED error_code stage1(const uint8_t *buf, size_t len, document::parser &parser, bool streaming) const noexcept final;
|
||||
WARN_UNUSED error_code stage2(const uint8_t *buf, size_t len, document::parser &parser) const noexcept final;
|
||||
WARN_UNUSED error_code stage2(const uint8_t *buf, size_t len, document::parser &parser, size_t &next_json) const noexcept final;
|
||||
WARN_UNUSED error_code stage1(const uint8_t *buf, size_t len, parser &parser, bool streaming) const noexcept final;
|
||||
WARN_UNUSED error_code stage2(const uint8_t *buf, size_t len, parser &parser) const noexcept final;
|
||||
WARN_UNUSED error_code stage2(const uint8_t *buf, size_t len, parser &parser, size_t &next_json) const noexcept final;
|
||||
};
|
||||
|
||||
} // namespace simdjson::arm64
|
||||
|
|
|
@ -81,7 +81,7 @@ WARN_UNUSED error_code implementation::minify(const uint8_t *buf, size_t len, ui
|
|||
|
||||
#include "generic/utf8_lookup2_algorithm.h"
|
||||
#include "generic/json_structural_indexer.h"
|
||||
WARN_UNUSED error_code implementation::stage1(const uint8_t *buf, size_t len, document::parser &parser, bool streaming) const noexcept {
|
||||
WARN_UNUSED error_code implementation::stage1(const uint8_t *buf, size_t len, parser &parser, bool streaming) const noexcept {
|
||||
return arm64::stage1::json_structural_indexer::index<64>(buf, len, parser, streaming);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,85 +3,85 @@
|
|||
|
||||
#include "simdjson.h"
|
||||
|
||||
namespace simdjson {
|
||||
namespace simdjson::dom {
|
||||
|
||||
//
|
||||
// Parser callbacks
|
||||
//
|
||||
|
||||
inline void document::parser::init_stage2() noexcept {
|
||||
inline void parser::init_stage2() noexcept {
|
||||
current_string_buf_loc = doc.string_buf.get();
|
||||
current_loc = 0;
|
||||
valid = false;
|
||||
error = UNINITIALIZED;
|
||||
}
|
||||
|
||||
really_inline error_code document::parser::on_error(error_code new_error_code) noexcept {
|
||||
really_inline error_code parser::on_error(error_code new_error_code) noexcept {
|
||||
error = new_error_code;
|
||||
return new_error_code;
|
||||
}
|
||||
really_inline error_code document::parser::on_success(error_code success_code) noexcept {
|
||||
really_inline error_code parser::on_success(error_code success_code) noexcept {
|
||||
error = success_code;
|
||||
valid = true;
|
||||
return success_code;
|
||||
}
|
||||
really_inline bool document::parser::on_start_document(uint32_t depth) noexcept {
|
||||
really_inline bool parser::on_start_document(uint32_t depth) noexcept {
|
||||
containing_scope_offset[depth] = current_loc;
|
||||
write_tape(0, internal::tape_type::ROOT);
|
||||
return true;
|
||||
}
|
||||
really_inline bool document::parser::on_start_object(uint32_t depth) noexcept {
|
||||
really_inline bool parser::on_start_object(uint32_t depth) noexcept {
|
||||
containing_scope_offset[depth] = current_loc;
|
||||
write_tape(0, internal::tape_type::START_OBJECT);
|
||||
return true;
|
||||
}
|
||||
really_inline bool document::parser::on_start_array(uint32_t depth) noexcept {
|
||||
really_inline bool parser::on_start_array(uint32_t depth) noexcept {
|
||||
containing_scope_offset[depth] = current_loc;
|
||||
write_tape(0, internal::tape_type::START_ARRAY);
|
||||
return true;
|
||||
}
|
||||
// TODO we're not checking this bool
|
||||
really_inline bool document::parser::on_end_document(uint32_t depth) noexcept {
|
||||
really_inline bool parser::on_end_document(uint32_t depth) noexcept {
|
||||
// write our doc.tape location to the header scope
|
||||
// The root scope gets written *at* the previous location.
|
||||
annotate_previous_loc(containing_scope_offset[depth], current_loc);
|
||||
write_tape(containing_scope_offset[depth], internal::tape_type::ROOT);
|
||||
return true;
|
||||
}
|
||||
really_inline bool document::parser::on_end_object(uint32_t depth) noexcept {
|
||||
really_inline bool parser::on_end_object(uint32_t depth) noexcept {
|
||||
// write our doc.tape location to the header scope
|
||||
write_tape(containing_scope_offset[depth], internal::tape_type::END_OBJECT);
|
||||
annotate_previous_loc(containing_scope_offset[depth], current_loc);
|
||||
return true;
|
||||
}
|
||||
really_inline bool document::parser::on_end_array(uint32_t depth) noexcept {
|
||||
really_inline bool parser::on_end_array(uint32_t depth) noexcept {
|
||||
// write our doc.tape location to the header scope
|
||||
write_tape(containing_scope_offset[depth], internal::tape_type::END_ARRAY);
|
||||
annotate_previous_loc(containing_scope_offset[depth], current_loc);
|
||||
return true;
|
||||
}
|
||||
|
||||
really_inline bool document::parser::on_true_atom() noexcept {
|
||||
really_inline bool parser::on_true_atom() noexcept {
|
||||
write_tape(0, internal::tape_type::TRUE_VALUE);
|
||||
return true;
|
||||
}
|
||||
really_inline bool document::parser::on_false_atom() noexcept {
|
||||
really_inline bool parser::on_false_atom() noexcept {
|
||||
write_tape(0, internal::tape_type::FALSE_VALUE);
|
||||
return true;
|
||||
}
|
||||
really_inline bool document::parser::on_null_atom() noexcept {
|
||||
really_inline bool parser::on_null_atom() noexcept {
|
||||
write_tape(0, internal::tape_type::NULL_VALUE);
|
||||
return true;
|
||||
}
|
||||
|
||||
really_inline uint8_t *document::parser::on_start_string() noexcept {
|
||||
really_inline uint8_t *parser::on_start_string() noexcept {
|
||||
/* we advance the point, accounting for the fact that we have a NULL
|
||||
* termination */
|
||||
write_tape(current_string_buf_loc - doc.string_buf.get(), internal::tape_type::STRING);
|
||||
return current_string_buf_loc + sizeof(uint32_t);
|
||||
}
|
||||
|
||||
really_inline bool document::parser::on_end_string(uint8_t *dst) noexcept {
|
||||
really_inline bool parser::on_end_string(uint8_t *dst) noexcept {
|
||||
uint32_t str_length = dst - (current_string_buf_loc + sizeof(uint32_t));
|
||||
// TODO check for overflow in case someone has a crazy string (>=4GB?)
|
||||
// But only add the overflow check when the document itself exceeds 4GB
|
||||
|
@ -94,18 +94,18 @@ really_inline bool document::parser::on_end_string(uint8_t *dst) noexcept {
|
|||
return true;
|
||||
}
|
||||
|
||||
really_inline bool document::parser::on_number_s64(int64_t value) noexcept {
|
||||
really_inline bool parser::on_number_s64(int64_t value) noexcept {
|
||||
write_tape(0, internal::tape_type::INT64);
|
||||
std::memcpy(&doc.tape[current_loc], &value, sizeof(value));
|
||||
++current_loc;
|
||||
return true;
|
||||
}
|
||||
really_inline bool document::parser::on_number_u64(uint64_t value) noexcept {
|
||||
really_inline bool parser::on_number_u64(uint64_t value) noexcept {
|
||||
write_tape(0, internal::tape_type::UINT64);
|
||||
doc.tape[current_loc++] = value;
|
||||
return true;
|
||||
}
|
||||
really_inline bool document::parser::on_number_double(double value) noexcept {
|
||||
really_inline bool parser::on_number_double(double value) noexcept {
|
||||
write_tape(0, internal::tape_type::DOUBLE);
|
||||
static_assert(sizeof(value) == sizeof(doc.tape[current_loc]), "mismatch size");
|
||||
memcpy(&doc.tape[current_loc++], &value, sizeof(double));
|
||||
|
@ -113,14 +113,14 @@ really_inline bool document::parser::on_number_double(double value) noexcept {
|
|||
return true;
|
||||
}
|
||||
|
||||
really_inline void document::parser::write_tape(uint64_t val, internal::tape_type t) noexcept {
|
||||
really_inline void parser::write_tape(uint64_t val, internal::tape_type t) noexcept {
|
||||
doc.tape[current_loc++] = val | ((static_cast<uint64_t>(static_cast<char>(t))) << 56);
|
||||
}
|
||||
|
||||
really_inline void document::parser::annotate_previous_loc(uint32_t saved_loc, uint64_t val) noexcept {
|
||||
really_inline void parser::annotate_previous_loc(uint32_t saved_loc, uint64_t val) noexcept {
|
||||
doc.tape[saved_loc] |= val;
|
||||
}
|
||||
|
||||
} // namespace simdjson
|
||||
} // namespace simdjson::dom
|
||||
|
||||
#endif // SIMDJSON_DOCUMENT_PARSER_CALLBACKS_H
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
namespace simdjson::fallback {
|
||||
|
||||
using namespace simdjson::dom;
|
||||
|
||||
class implementation final : public simdjson::implementation {
|
||||
public:
|
||||
really_inline implementation() : simdjson::implementation(
|
||||
|
@ -13,11 +15,11 @@ public:
|
|||
"Generic fallback implementation",
|
||||
0
|
||||
) {}
|
||||
WARN_UNUSED error_code parse(const uint8_t *buf, size_t len, document::parser &parser) const noexcept final;
|
||||
WARN_UNUSED error_code parse(const uint8_t *buf, size_t len, parser &parser) const noexcept final;
|
||||
WARN_UNUSED error_code minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept final;
|
||||
WARN_UNUSED error_code stage1(const uint8_t *buf, size_t len, document::parser &parser, bool streaming) const noexcept final;
|
||||
WARN_UNUSED error_code stage2(const uint8_t *buf, size_t len, document::parser &parser) const noexcept final;
|
||||
WARN_UNUSED error_code stage2(const uint8_t *buf, size_t len, document::parser &parser, size_t &next_json) const noexcept final;
|
||||
WARN_UNUSED error_code stage1(const uint8_t *buf, size_t len, parser &parser, bool streaming) const noexcept final;
|
||||
WARN_UNUSED error_code stage2(const uint8_t *buf, size_t len, parser &parser) const noexcept final;
|
||||
WARN_UNUSED error_code stage2(const uint8_t *buf, size_t len, parser &parser, size_t &next_json) const noexcept final;
|
||||
};
|
||||
|
||||
} // namespace simdjson::fallback
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace simdjson::fallback::stage1 {
|
|||
class structural_scanner {
|
||||
public:
|
||||
|
||||
really_inline structural_scanner(const uint8_t *_buf, uint32_t _len, document::parser &_doc_parser, bool _streaming)
|
||||
really_inline structural_scanner(const uint8_t *_buf, uint32_t _len, parser &_doc_parser, bool _streaming)
|
||||
: buf{_buf}, next_structural_index{_doc_parser.structural_indexes.get()}, doc_parser{_doc_parser}, idx{0}, len{_len}, error{SUCCESS}, streaming{_streaming} {}
|
||||
|
||||
really_inline void add_structural() {
|
||||
|
@ -132,7 +132,7 @@ really_inline error_code scan() {
|
|||
private:
|
||||
const uint8_t *buf;
|
||||
uint32_t *next_structural_index;
|
||||
document::parser &doc_parser;
|
||||
parser &doc_parser;
|
||||
uint32_t idx;
|
||||
uint32_t len;
|
||||
error_code error;
|
||||
|
@ -143,7 +143,7 @@ private:
|
|||
|
||||
namespace simdjson::fallback {
|
||||
|
||||
WARN_UNUSED error_code implementation::stage1(const uint8_t *buf, size_t len, document::parser &parser, bool streaming) const noexcept {
|
||||
WARN_UNUSED error_code implementation::stage1(const uint8_t *buf, size_t len, parser &parser, bool streaming) const noexcept {
|
||||
if (unlikely(len > parser.capacity())) {
|
||||
return CAPACITY;
|
||||
}
|
||||
|
|
|
@ -58,14 +58,14 @@ public:
|
|||
class json_structural_indexer {
|
||||
public:
|
||||
template<size_t STEP_SIZE>
|
||||
static error_code index(const uint8_t *buf, size_t len, document::parser &parser, bool streaming) noexcept;
|
||||
static error_code index(const uint8_t *buf, size_t len, parser &parser, bool streaming) noexcept;
|
||||
|
||||
private:
|
||||
really_inline json_structural_indexer(uint32_t *structural_indexes) : indexer{structural_indexes} {}
|
||||
template<size_t STEP_SIZE>
|
||||
really_inline void step(const uint8_t *block, buf_block_reader<STEP_SIZE> &reader) noexcept;
|
||||
really_inline void next(simd::simd8x64<uint8_t> in, json_block block, size_t idx);
|
||||
really_inline error_code finish(document::parser &parser, size_t idx, size_t len, bool streaming);
|
||||
really_inline error_code finish(parser &parser, size_t idx, size_t len, bool streaming);
|
||||
|
||||
json_scanner scanner;
|
||||
utf8_checker checker{};
|
||||
|
@ -82,7 +82,7 @@ really_inline void json_structural_indexer::next(simd::simd8x64<uint8_t> in, jso
|
|||
unescaped_chars_error |= block.non_quote_inside_string(unescaped);
|
||||
}
|
||||
|
||||
really_inline error_code json_structural_indexer::finish(document::parser &parser, size_t idx, size_t len, bool streaming) {
|
||||
really_inline error_code json_structural_indexer::finish(parser &parser, size_t idx, size_t len, bool streaming) {
|
||||
// Write out the final iteration's structurals
|
||||
indexer.write(idx-64, prev_structurals);
|
||||
|
||||
|
@ -154,7 +154,7 @@ really_inline void json_structural_indexer::step<64>(const uint8_t *block, buf_b
|
|||
// The caller should still ensure that the input is valid UTF-8. If you are processing substrings,
|
||||
// you may want to call on a function like trimmed_length_safe_utf8.
|
||||
template<size_t STEP_SIZE>
|
||||
error_code json_structural_indexer::index(const uint8_t *buf, size_t len, document::parser &parser, bool streaming) noexcept {
|
||||
error_code json_structural_indexer::index(const uint8_t *buf, size_t len, parser &parser, bool streaming) noexcept {
|
||||
if (unlikely(len > parser.capacity())) { return CAPACITY; }
|
||||
|
||||
buf_block_reader<STEP_SIZE> reader(buf, len);
|
||||
|
|
|
@ -262,7 +262,7 @@ really_inline bool is_made_of_eight_digits_fast(const char *chars) {
|
|||
// This function will almost never be called!!!
|
||||
//
|
||||
never_inline bool parse_large_integer(const uint8_t *const src,
|
||||
document::parser &parser,
|
||||
parser &parser,
|
||||
bool found_minus) {
|
||||
const char *p = reinterpret_cast<const char *>(src);
|
||||
|
||||
|
@ -341,7 +341,7 @@ never_inline bool parse_large_integer(const uint8_t *const src,
|
|||
return is_structural_or_whitespace(*p);
|
||||
}
|
||||
|
||||
bool slow_float_parsing(UNUSED const char * src, document::parser &parser) {
|
||||
bool slow_float_parsing(UNUSED const char * src, parser &parser) {
|
||||
double d;
|
||||
if (parse_float_strtod(src, &d)) {
|
||||
parser.on_number_double(d);
|
||||
|
@ -367,7 +367,7 @@ bool slow_float_parsing(UNUSED const char * src, document::parser &parser) {
|
|||
// Our objective is accurate parsing (ULP of 0) at high speed.
|
||||
really_inline bool parse_number(UNUSED const uint8_t *const src,
|
||||
UNUSED bool found_minus,
|
||||
document::parser &parser) {
|
||||
parser &parser) {
|
||||
#ifdef SIMDJSON_SKIPNUMBERPARSING // for performance analysis, it is sometimes
|
||||
// useful to skip parsing
|
||||
parser.on_number_s64(0); // always write zero
|
||||
|
|
|
@ -111,13 +111,13 @@ public:
|
|||
|
||||
struct structural_parser {
|
||||
structural_iterator structurals;
|
||||
document::parser &doc_parser;
|
||||
parser &doc_parser;
|
||||
uint32_t depth;
|
||||
|
||||
really_inline structural_parser(
|
||||
const uint8_t *buf,
|
||||
size_t len,
|
||||
document::parser &_doc_parser,
|
||||
parser &_doc_parser,
|
||||
uint32_t next_structural = 0
|
||||
) : structurals(buf, len, _doc_parser.structural_indexes.get(), next_structural), doc_parser{_doc_parser}, depth{0} {}
|
||||
|
||||
|
@ -325,7 +325,7 @@ struct structural_parser {
|
|||
* The JSON is parsed to a tape, see the accompanying tape.md file
|
||||
* for documentation.
|
||||
***********/
|
||||
WARN_UNUSED error_code implementation::stage2(const uint8_t *buf, size_t len, document::parser &doc_parser) const noexcept {
|
||||
WARN_UNUSED error_code implementation::stage2(const uint8_t *buf, size_t len, parser &doc_parser) const noexcept {
|
||||
static constexpr stage2::unified_machine_addresses addresses = INIT_ADDRESSES();
|
||||
stage2::structural_parser parser(buf, len, doc_parser);
|
||||
error_code result = parser.start(len, addresses.finish);
|
||||
|
@ -436,7 +436,7 @@ error:
|
|||
return parser.error();
|
||||
}
|
||||
|
||||
WARN_UNUSED error_code implementation::parse(const uint8_t *buf, size_t len, document::parser &doc_parser) const noexcept {
|
||||
WARN_UNUSED error_code implementation::parse(const uint8_t *buf, size_t len, parser &doc_parser) const noexcept {
|
||||
error_code code = stage1(buf, len, doc_parser, false);
|
||||
if (!code) {
|
||||
code = stage2(buf, len, doc_parser);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
namespace stage2 {
|
||||
|
||||
struct streaming_structural_parser: structural_parser {
|
||||
really_inline streaming_structural_parser(const uint8_t *_buf, size_t _len, document::parser &_doc_parser, size_t _i) : structural_parser(_buf, _len, _doc_parser, _i) {}
|
||||
really_inline streaming_structural_parser(const uint8_t *_buf, size_t _len, parser &_doc_parser, size_t _i) : structural_parser(_buf, _len, _doc_parser, _i) {}
|
||||
|
||||
// override to add streaming
|
||||
WARN_UNUSED really_inline error_code start(UNUSED size_t len, ret_address finish_parser) {
|
||||
|
@ -39,7 +39,7 @@ struct streaming_structural_parser: structural_parser {
|
|||
* The JSON is parsed to a tape, see the accompanying tape.md file
|
||||
* for documentation.
|
||||
***********/
|
||||
WARN_UNUSED error_code implementation::stage2(const uint8_t *buf, size_t len, document::parser &doc_parser, size_t &next_json) const noexcept {
|
||||
WARN_UNUSED error_code implementation::stage2(const uint8_t *buf, size_t len, parser &doc_parser, size_t &next_json) const noexcept {
|
||||
static constexpr stage2::unified_machine_addresses addresses = INIT_ADDRESSES();
|
||||
stage2::streaming_structural_parser parser(buf, len, doc_parser, next_json);
|
||||
error_code result = parser.start(len, addresses.finish);
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
namespace simdjson::haswell {
|
||||
|
||||
using namespace simdjson::dom;
|
||||
|
||||
class implementation final : public simdjson::implementation {
|
||||
public:
|
||||
really_inline implementation() : simdjson::implementation(
|
||||
|
@ -13,11 +15,11 @@ public:
|
|||
"Intel/AMD AVX2",
|
||||
instruction_set::AVX2 | instruction_set::PCLMULQDQ | instruction_set::BMI1 | instruction_set::BMI2
|
||||
) {}
|
||||
WARN_UNUSED error_code parse(const uint8_t *buf, size_t len, document::parser &parser) const noexcept final;
|
||||
WARN_UNUSED error_code parse(const uint8_t *buf, size_t len, parser &parser) const noexcept final;
|
||||
WARN_UNUSED error_code minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept final;
|
||||
WARN_UNUSED error_code stage1(const uint8_t *buf, size_t len, document::parser &parser, bool streaming) const noexcept final;
|
||||
WARN_UNUSED error_code stage2(const uint8_t *buf, size_t len, document::parser &parser) const noexcept final;
|
||||
WARN_UNUSED error_code stage2(const uint8_t *buf, size_t len, document::parser &parser, size_t &next_json) const noexcept final;
|
||||
WARN_UNUSED error_code stage1(const uint8_t *buf, size_t len, parser &parser, bool streaming) const noexcept final;
|
||||
WARN_UNUSED error_code stage2(const uint8_t *buf, size_t len, parser &parser) const noexcept final;
|
||||
WARN_UNUSED error_code stage2(const uint8_t *buf, size_t len, parser &parser, size_t &next_json) const noexcept final;
|
||||
};
|
||||
|
||||
} // namespace simdjson::haswell
|
||||
|
|
|
@ -70,7 +70,7 @@ WARN_UNUSED error_code implementation::minify(const uint8_t *buf, size_t len, ui
|
|||
|
||||
#include "generic/utf8_lookup2_algorithm.h"
|
||||
#include "generic/json_structural_indexer.h"
|
||||
WARN_UNUSED error_code implementation::stage1(const uint8_t *buf, size_t len, document::parser &parser, bool streaming) const noexcept {
|
||||
WARN_UNUSED error_code implementation::stage1(const uint8_t *buf, size_t len, parser &parser, bool streaming) const noexcept {
|
||||
return haswell::stage1::json_structural_indexer::index<128>(buf, len, parser, streaming);
|
||||
}
|
||||
|
||||
|
|
|
@ -47,19 +47,19 @@ constexpr const std::initializer_list<const implementation *> available_implemen
|
|||
// So we can return UNSUPPORTED_ARCHITECTURE from the parser when there is no support
|
||||
class unsupported_implementation final : public implementation {
|
||||
public:
|
||||
WARN_UNUSED error_code parse(const uint8_t *, size_t, document::parser &) const noexcept final {
|
||||
WARN_UNUSED error_code parse(const uint8_t *, size_t, parser &) const noexcept final {
|
||||
return UNSUPPORTED_ARCHITECTURE;
|
||||
}
|
||||
WARN_UNUSED error_code minify(const uint8_t *, size_t, uint8_t *, size_t &) const noexcept final {
|
||||
return UNSUPPORTED_ARCHITECTURE;
|
||||
}
|
||||
WARN_UNUSED error_code stage1(const uint8_t *, size_t, document::parser &, bool) const noexcept final {
|
||||
WARN_UNUSED error_code stage1(const uint8_t *, size_t, parser &, bool) const noexcept final {
|
||||
return UNSUPPORTED_ARCHITECTURE;
|
||||
}
|
||||
WARN_UNUSED error_code stage2(const uint8_t *, size_t, document::parser &) const noexcept final {
|
||||
WARN_UNUSED error_code stage2(const uint8_t *, size_t, parser &) const noexcept final {
|
||||
return UNSUPPORTED_ARCHITECTURE;
|
||||
}
|
||||
WARN_UNUSED error_code stage2(const uint8_t *, size_t, document::parser &, size_t &) const noexcept final {
|
||||
WARN_UNUSED error_code stage2(const uint8_t *, size_t, parser &, size_t &) const noexcept final {
|
||||
return UNSUPPORTED_ARCHITECTURE;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,14 +7,16 @@
|
|||
|
||||
namespace simdjson::westmere {
|
||||
|
||||
using namespace simdjson::dom;
|
||||
|
||||
class implementation final : public simdjson::implementation {
|
||||
public:
|
||||
really_inline implementation() : simdjson::implementation("westmere", "Intel/AMD SSE4.2", instruction_set::SSE42 | instruction_set::PCLMULQDQ) {}
|
||||
WARN_UNUSED error_code parse(const uint8_t *buf, size_t len, document::parser &parser) const noexcept final;
|
||||
WARN_UNUSED error_code parse(const uint8_t *buf, size_t len, parser &parser) const noexcept final;
|
||||
WARN_UNUSED error_code minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept final;
|
||||
WARN_UNUSED error_code stage1(const uint8_t *buf, size_t len, document::parser &parser, bool streaming) const noexcept final;
|
||||
WARN_UNUSED error_code stage2(const uint8_t *buf, size_t len, document::parser &parser) const noexcept final;
|
||||
WARN_UNUSED error_code stage2(const uint8_t *buf, size_t len, document::parser &parser, size_t &next_json) const noexcept final;
|
||||
WARN_UNUSED error_code stage1(const uint8_t *buf, size_t len, parser &parser, bool streaming) const noexcept final;
|
||||
WARN_UNUSED error_code stage2(const uint8_t *buf, size_t len, parser &parser) const noexcept final;
|
||||
WARN_UNUSED error_code stage2(const uint8_t *buf, size_t len, parser &parser, size_t &next_json) const noexcept final;
|
||||
};
|
||||
|
||||
} // namespace simdjson::westmere
|
||||
|
|
|
@ -69,7 +69,7 @@ WARN_UNUSED error_code implementation::minify(const uint8_t *buf, size_t len, ui
|
|||
|
||||
#include "generic/utf8_lookup2_algorithm.h"
|
||||
#include "generic/json_structural_indexer.h"
|
||||
WARN_UNUSED error_code implementation::stage1(const uint8_t *buf, size_t len, document::parser &parser, bool streaming) const noexcept {
|
||||
WARN_UNUSED error_code implementation::stage1(const uint8_t *buf, size_t len, parser &parser, bool streaming) const noexcept {
|
||||
return westmere::stage1::json_structural_indexer::index<64>(buf, len, parser, streaming);
|
||||
}
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ int main(int argc, char *argv[]) {
|
|||
std::cout << p.size() << " B ";
|
||||
std::cout << std::endl;
|
||||
}
|
||||
simdjson::document::parser parser;
|
||||
simdjson::dom::parser parser;
|
||||
auto [doc, err] = parser.parse(p);
|
||||
|
||||
rapidjson::Document d;
|
||||
|
|
|
@ -42,7 +42,7 @@ namespace number_tests {
|
|||
bool small_integers() {
|
||||
std::cout << __func__ << std::endl;
|
||||
char buf[1024];
|
||||
simdjson::document::parser parser;
|
||||
simdjson::dom::parser parser;
|
||||
for (int m = 10; m < 20; m++) {
|
||||
for (int i = -1024; i < 1024; i++) {
|
||||
auto n = sprintf(buf, "%*d", m, i);
|
||||
|
@ -63,7 +63,7 @@ namespace number_tests {
|
|||
bool powers_of_two() {
|
||||
std::cout << __func__ << std::endl;
|
||||
char buf[1024];
|
||||
simdjson::document::parser parser;
|
||||
simdjson::dom::parser parser;
|
||||
int maxulp = 0;
|
||||
for (int i = -1075; i < 1024; ++i) {// large negative values should be zero.
|
||||
double expected = pow(2, i);
|
||||
|
@ -158,7 +158,7 @@ namespace number_tests {
|
|||
bool powers_of_ten() {
|
||||
std::cout << __func__ << std::endl;
|
||||
char buf[1024];
|
||||
simdjson::document::parser parser;
|
||||
simdjson::dom::parser parser;
|
||||
for (int i = -1000000; i <= 308; ++i) {// large negative values should be zero.
|
||||
auto n = sprintf(buf,"1e%d", i);
|
||||
buf[n] = '\0';
|
||||
|
@ -188,7 +188,7 @@ namespace document_tests {
|
|||
bool bad_example() {
|
||||
std::cout << __func__ << std::endl;
|
||||
simdjson::padded_string badjson = "[7,7,7,7,6,7,7,7,6,7,7,6,[7,7,7,7,6,7,7,7,6,7,7,6,7,7,7,7,7,7,6"_padded;
|
||||
simdjson::document::parser parser;
|
||||
simdjson::dom::parser parser;
|
||||
auto [doc, error] = parser.parse(badjson);
|
||||
if (!error) {
|
||||
printf("This json should not be valid %s.\n", badjson.data());
|
||||
|
@ -213,7 +213,7 @@ namespace document_tests {
|
|||
"\"IDs\":[116,943.3,234,38793]"
|
||||
"}"
|
||||
"}"_padded;
|
||||
simdjson::document::parser parser;
|
||||
simdjson::dom::parser parser;
|
||||
std::ostringstream myStream;
|
||||
myStream << parser.parse(json);
|
||||
std::string newjson = myStream.str();
|
||||
|
@ -255,7 +255,7 @@ namespace document_tests {
|
|||
if (maxsize < s.size())
|
||||
maxsize = s.size();
|
||||
}
|
||||
simdjson::document::parser parser;
|
||||
simdjson::dom::parser parser;
|
||||
size_t counter = 0;
|
||||
for (auto &rec : data) {
|
||||
if ((counter % 10000) == 0) {
|
||||
|
@ -287,7 +287,7 @@ namespace document_tests {
|
|||
for(size_t i = 0; i < 200; i++) {
|
||||
input += "]";
|
||||
}
|
||||
simdjson::document::parser parser;
|
||||
simdjson::dom::parser parser;
|
||||
auto [doc, error] = parser.parse(input);
|
||||
if (error) { std::cerr << "Error: " << simdjson::error_message(error) << std::endl; return false; }
|
||||
return true;
|
||||
|
@ -302,18 +302,18 @@ namespace document_tests {
|
|||
|
||||
namespace document_stream_tests {
|
||||
|
||||
static simdjson::document::stream parse_many_stream_return(simdjson::document::parser &parser, simdjson::padded_string &str) {
|
||||
static simdjson::dom::stream parse_many_stream_return(simdjson::dom::parser &parser, simdjson::padded_string &str) {
|
||||
return parser.parse_many(str);
|
||||
}
|
||||
// this is a compilation test
|
||||
UNUSED static void parse_many_stream_assign() {
|
||||
simdjson::document::parser parser;
|
||||
simdjson::dom::parser parser;
|
||||
simdjson::padded_string str("{}",2);
|
||||
simdjson::document::stream s1 = parse_many_stream_return(parser, str);
|
||||
simdjson::dom::stream s1 = parse_many_stream_return(parser, str);
|
||||
}
|
||||
|
||||
static bool parse_json_message_issue467(simdjson::padded_string &json, size_t expectedcount) {
|
||||
simdjson::document::parser parser;
|
||||
simdjson::dom::parser parser;
|
||||
size_t count = 0;
|
||||
for (auto [doc, error] : parser.parse_many(json)) {
|
||||
if (error) {
|
||||
|
@ -361,7 +361,7 @@ namespace document_stream_tests {
|
|||
printf(".");
|
||||
fflush(NULL);
|
||||
simdjson::padded_string str(data);
|
||||
simdjson::document::parser parser;
|
||||
simdjson::dom::parser parser;
|
||||
size_t count = 0;
|
||||
for (auto [doc, error] : parser.parse_many(str, batch_size)) {
|
||||
if (error) {
|
||||
|
@ -409,7 +409,7 @@ namespace document_stream_tests {
|
|||
printf(".");
|
||||
fflush(NULL);
|
||||
simdjson::padded_string str(data);
|
||||
simdjson::document::parser parser;
|
||||
simdjson::dom::parser parser;
|
||||
size_t count = 0;
|
||||
for (auto [doc, error] : parser.parse_many(str, batch_size)) {
|
||||
if (error) {
|
||||
|
@ -448,6 +448,7 @@ namespace document_stream_tests {
|
|||
namespace parse_api_tests {
|
||||
using namespace std;
|
||||
using namespace simdjson;
|
||||
using namespace simdjson::dom;
|
||||
|
||||
const padded_string BASIC_JSON = string("[1,2,3]");
|
||||
const padded_string BASIC_NDJSON = string("[1,2,3]\n[4,5,6]");
|
||||
|
@ -455,7 +456,7 @@ namespace parse_api_tests {
|
|||
|
||||
bool parser_parse() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
auto [doc, error] = parser.parse(BASIC_JSON);
|
||||
if (error) { cerr << error << endl; return false; }
|
||||
if (!doc.is_array()) { cerr << "Document did not parse as an array" << endl; return false; }
|
||||
|
@ -463,7 +464,7 @@ namespace parse_api_tests {
|
|||
}
|
||||
bool parser_parse_many() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
int count = 0;
|
||||
for (auto [doc, error] : parser.parse_many(BASIC_NDJSON)) {
|
||||
if (error) { cerr << error << endl; return false; }
|
||||
|
@ -475,7 +476,7 @@ namespace parse_api_tests {
|
|||
}
|
||||
// bool parser_parse_many_empty() {
|
||||
// std::cout << "Running " << __func__ << std::endl;
|
||||
// document::parser parser;
|
||||
// dom::parser parser;
|
||||
// int count = 0;
|
||||
// for (auto [doc, error] : parser.parse_many(EMPTY_NDJSON)) {
|
||||
// if (error) { cerr << error << endl; return false; }
|
||||
|
@ -487,7 +488,7 @@ namespace parse_api_tests {
|
|||
|
||||
bool parser_load() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
auto [doc, error] = parser.load(JSON_TEST_PATH);
|
||||
if (error) { cerr << error << endl; return false; }
|
||||
if (!doc.is_object()) { cerr << "Document did not parse as an object" << endl; return false; }
|
||||
|
@ -495,7 +496,7 @@ namespace parse_api_tests {
|
|||
}
|
||||
bool parser_load_many() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
int count = 0;
|
||||
for (auto [doc, error] : parser.load_many(NDJSON_TEST_PATH)) {
|
||||
if (error) { cerr << error << endl; return false; }
|
||||
|
@ -510,16 +511,16 @@ namespace parse_api_tests {
|
|||
|
||||
bool parser_parse_exception() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
document::parser parser;
|
||||
document::element doc = parser.parse(BASIC_JSON);
|
||||
dom::parser parser;
|
||||
element doc = parser.parse(BASIC_JSON);
|
||||
if (!doc.is_array()) { cerr << "Document did not parse as an array" << endl; return false; }
|
||||
return true;
|
||||
}
|
||||
bool parser_parse_many_exception() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
int count = 0;
|
||||
for (const document::element doc : parser.parse_many(BASIC_NDJSON)) {
|
||||
for (const element doc : parser.parse_many(BASIC_NDJSON)) {
|
||||
if (!doc.is_array()) { cerr << "Document did not parse as an array" << endl; return false; }
|
||||
count++;
|
||||
}
|
||||
|
@ -529,16 +530,16 @@ namespace parse_api_tests {
|
|||
|
||||
bool parser_load_exception() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
document::parser parser;
|
||||
const document::element doc = parser.load(JSON_TEST_PATH);
|
||||
dom::parser parser;
|
||||
const element doc = parser.load(JSON_TEST_PATH);
|
||||
if (!doc.is_object()) { cerr << "Document did not parse as an object" << endl; return false; }
|
||||
return true;
|
||||
}
|
||||
bool parser_load_many_exception() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
int count = 0;
|
||||
for (const document::element doc : parser.load_many(NDJSON_TEST_PATH)) {
|
||||
for (const element doc : parser.load_many(NDJSON_TEST_PATH)) {
|
||||
if (!doc.is_array()) { cerr << "Document did not parse as an array" << endl; return false; }
|
||||
count++;
|
||||
}
|
||||
|
@ -566,6 +567,7 @@ namespace parse_api_tests {
|
|||
namespace dom_api_tests {
|
||||
using namespace std;
|
||||
using namespace simdjson;
|
||||
using namespace simdjson::dom;
|
||||
|
||||
SIMDJSON_PUSH_DISABLE_WARNINGS
|
||||
SIMDJSON_DISABLE_DEPRECATED_WARNING
|
||||
|
@ -679,7 +681,7 @@ namespace dom_api_tests {
|
|||
uint64_t expected_value[] = { 1, 2, 3 };
|
||||
int i = 0;
|
||||
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
auto [object, error] = parser.parse(json).as_object();
|
||||
if (error) { cerr << "Error: " << error << endl; return false; }
|
||||
for (auto [key, value] : object) {
|
||||
|
@ -696,7 +698,7 @@ namespace dom_api_tests {
|
|||
uint64_t expected_value[] = { 1, 10, 100 };
|
||||
int i=0;
|
||||
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
auto [array, error] = parser.parse(json).as_array();
|
||||
if (error) { cerr << "Error: " << error << endl; return false; }
|
||||
for (auto value : array) {
|
||||
|
@ -712,7 +714,7 @@ namespace dom_api_tests {
|
|||
string json(R"({})");
|
||||
int i = 0;
|
||||
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
auto [object, error] = parser.parse(json).as_object();
|
||||
if (error) { cerr << "Error: " << error << endl; return false; }
|
||||
for (auto [key, value] : object) {
|
||||
|
@ -728,7 +730,7 @@ namespace dom_api_tests {
|
|||
string json(R"([])");
|
||||
int i=0;
|
||||
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
auto [array, error] = parser.parse(json).as_array();
|
||||
if (error) { cerr << "Error: " << error << endl; return false; }
|
||||
for (auto value : array) {
|
||||
|
@ -742,7 +744,7 @@ namespace dom_api_tests {
|
|||
bool string_value() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
string json(R"([ "hi", "has backslash\\" ])");
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
auto [array, error] = parser.parse(json).as_array();
|
||||
if (error) { cerr << "Error: " << error << endl; return false; }
|
||||
auto val = array.begin();
|
||||
|
@ -756,7 +758,7 @@ namespace dom_api_tests {
|
|||
bool numeric_values() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
string json(R"([ 0, 1, -1, 1.1 ])");
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
auto [array, error] = parser.parse(json).as_array();
|
||||
if (error) { cerr << "Error: " << error << endl; return false; }
|
||||
auto val = array.begin();
|
||||
|
@ -779,7 +781,7 @@ namespace dom_api_tests {
|
|||
bool boolean_values() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
string json(R"([ true, false ])");
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
auto [array, error] = parser.parse(json).as_array();
|
||||
if (error) { cerr << "Error: " << error << endl; return false; }
|
||||
auto val = array.begin();
|
||||
|
@ -793,7 +795,7 @@ namespace dom_api_tests {
|
|||
bool null_value() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
string json(R"([ null ])");
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
auto [array, error] = parser.parse(json).as_array();
|
||||
if (error) { cerr << "Error: " << error << endl; return false; }
|
||||
auto val = array.begin();
|
||||
|
@ -804,7 +806,7 @@ namespace dom_api_tests {
|
|||
bool document_object_index() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
string json(R"({ "a": 1, "b": 2, "c": 3})");
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
auto [doc, error] = parser.parse(json);
|
||||
if (doc["a"].as_uint64_t().first != 1) { cerr << "Expected uint64_t(doc[\"a\"]) to be 1, was " << doc["a"].first << endl; return false; }
|
||||
if (doc["b"].as_uint64_t().first != 2) { cerr << "Expected uint64_t(doc[\"b\"]) to be 2, was " << doc["b"].first << endl; return false; }
|
||||
|
@ -814,7 +816,7 @@ namespace dom_api_tests {
|
|||
if (doc["b"].as_uint64_t().first != 2) { cerr << "Expected uint64_t(doc[\"b\"]) to be 2, was " << doc["b"].first << endl; return false; }
|
||||
if (doc["a"].as_uint64_t().first != 1) { cerr << "Expected uint64_t(doc[\"a\"]) to be 1, was " << doc["a"].first << endl; return false; }
|
||||
|
||||
UNUSED document::element val;
|
||||
UNUSED element val;
|
||||
// tie(val, error) = doc["d"]; fails with "no viable overloaded '='" on Apple clang version 11.0.0 tie(val, error) = doc["d"];
|
||||
doc["d"].tie(val, error);
|
||||
if (error != simdjson::NO_SUCH_FIELD) { cerr << "Expected NO_SUCH_FIELD error for uint64_t(doc[\"d\"]), got " << error << endl; return false; }
|
||||
|
@ -824,12 +826,12 @@ namespace dom_api_tests {
|
|||
bool object_index() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
string json(R"({ "obj": { "a": 1, "b": 2, "c": 3 } })");
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
auto [doc, error] = parser.parse(json);
|
||||
if (error) { cerr << "Error: " << error << endl; return false; }
|
||||
if (doc["obj"]["a"].as_uint64_t().first != 1) { cerr << "Expected uint64_t(doc[\"obj\"][\"a\"]) to be 1, was " << doc["obj"]["a"].first << endl; return false; }
|
||||
|
||||
document::object obj;
|
||||
object obj;
|
||||
doc.as_object().tie(obj, error); // tie(...) = fails with "no viable overloaded '='" on Apple clang version 11.0.0
|
||||
if (error) { cerr << "Error: " << error << endl; return false; }
|
||||
if (obj["obj"]["a"].as_uint64_t().first != 1) { cerr << "Expected uint64_t(doc[\"obj\"][\"a\"]) to be 1, was " << doc["obj"]["a"].first << endl; return false; }
|
||||
|
@ -843,7 +845,7 @@ namespace dom_api_tests {
|
|||
if (obj["b"].as_uint64_t().first != 2) { cerr << "Expected uint64_t(obj[\"b\"]) to be 2, was " << obj["b"].first << endl; return false; }
|
||||
if (obj["a"].as_uint64_t().first != 1) { cerr << "Expected uint64_t(obj[\"a\"]) to be 1, was " << obj["a"].first << endl; return false; }
|
||||
|
||||
UNUSED document::element val;
|
||||
UNUSED element val;
|
||||
doc["d"].tie(val, error); // tie(...) = fails with "no viable overloaded '='" on Apple clang version 11.0.0;
|
||||
if (error != simdjson::NO_SUCH_FIELD) { cerr << "Expected NO_SUCH_FIELD error for uint64_t(obj[\"d\"]), got " << error << endl; return false; }
|
||||
return true;
|
||||
|
@ -852,7 +854,7 @@ namespace dom_api_tests {
|
|||
bool twitter_count() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
// Prints the number of results in twitter.json
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
auto [result_count, error] = parser.load(JSON_TEST_PATH)["search_metadata"]["count"].as_uint64_t();
|
||||
if (error) { cerr << "Error: " << error << endl; return false; }
|
||||
if (result_count != 100) { cerr << "Expected twitter.json[metadata_count][count] = 100, got " << result_count << endl; return false; }
|
||||
|
@ -863,11 +865,11 @@ namespace dom_api_tests {
|
|||
std::cout << "Running " << __func__ << std::endl;
|
||||
// Print users with a default profile.
|
||||
set<string_view> default_users;
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
auto [tweets, error] = parser.load(JSON_TEST_PATH)["statuses"].as_array();
|
||||
if (error) { cerr << "Error: " << error << endl; return false; }
|
||||
for (auto tweet : tweets) {
|
||||
document::object user;
|
||||
object user;
|
||||
tweet["user"].as_object().tie(user, error); // tie(...) = fails with "no viable overloaded '='" on Apple clang version 11.0.0;
|
||||
if (error) { cerr << "Error: " << error << endl; return false; }
|
||||
bool default_profile;
|
||||
|
@ -888,14 +890,14 @@ namespace dom_api_tests {
|
|||
std::cout << "Running " << __func__ << std::endl;
|
||||
// Print image names and sizes
|
||||
set<pair<uint64_t, uint64_t>> image_sizes;
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
auto [tweets, error] = parser.load(JSON_TEST_PATH)["statuses"].as_array();
|
||||
if (error) { cerr << "Error: " << error << endl; return false; }
|
||||
for (auto tweet : tweets) {
|
||||
auto [media, not_found] = tweet["entities"]["media"].as_array();
|
||||
if (!not_found) {
|
||||
for (auto image : media) {
|
||||
document::object sizes;
|
||||
object sizes;
|
||||
image["sizes"].as_object().tie(sizes, error); // tie(...) = fails with "no viable overloaded '='" on Apple clang version 11.0.0;
|
||||
if (error) { cerr << "Error: " << error << endl; return false; }
|
||||
for (auto [key, size] : sizes) {
|
||||
|
@ -922,8 +924,8 @@ namespace dom_api_tests {
|
|||
uint64_t expected_value[] = { 1, 2, 3 };
|
||||
int i = 0;
|
||||
|
||||
document::parser parser;
|
||||
document::element doc = parser.parse(json);
|
||||
dom::parser parser;
|
||||
element doc = parser.parse(json);
|
||||
for (auto [key, value] : doc.as_object()) {
|
||||
if (key != expected_key[i] || uint64_t(value) != expected_value[i]) { cerr << "Expected " << expected_key[i] << " = " << expected_value[i] << ", got " << key << "=" << uint64_t(value) << endl; return false; }
|
||||
i++;
|
||||
|
@ -938,8 +940,8 @@ namespace dom_api_tests {
|
|||
uint64_t expected_value[] = { 1, 10, 100 };
|
||||
int i=0;
|
||||
|
||||
document::parser parser;
|
||||
document::element doc = parser.parse(json);
|
||||
dom::parser parser;
|
||||
element doc = parser.parse(json);
|
||||
for (uint64_t value : doc.as_array()) {
|
||||
if (value != expected_value[i]) { cerr << "Expected " << expected_value[i] << ", got " << value << endl; return false; }
|
||||
i++;
|
||||
|
@ -951,9 +953,8 @@ namespace dom_api_tests {
|
|||
bool string_value_exception() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
string json(R"([ "hi", "has backslash\\" ])");
|
||||
document::parser parser;
|
||||
document::array array = parser.parse(json).as_array();
|
||||
auto val = array.begin();
|
||||
dom::parser parser;
|
||||
auto val = parser.parse(json).as_array().begin();
|
||||
|
||||
if (strcmp((const char*)*val, "hi")) { cerr << "Expected const char*(\"hi\") to be \"hi\", was " << (const char*)*val << endl; return false; }
|
||||
if (string_view(*val) != "hi") { cerr << "Expected string_view(\"hi\") to be \"hi\", was " << string_view(*val) << endl; return false; }
|
||||
|
@ -966,9 +967,8 @@ namespace dom_api_tests {
|
|||
bool numeric_values_exception() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
string json(R"([ 0, 1, -1, 1.1 ])");
|
||||
document::parser parser;
|
||||
document::array array = parser.parse(json).as_array();
|
||||
auto val = array.begin();
|
||||
dom::parser parser;
|
||||
auto val = parser.parse(json).as_array().begin();
|
||||
|
||||
if (uint64_t(*val) != 0) { cerr << "Expected uint64_t(0) to be 0, was " << uint64_t(*val) << endl; return false; }
|
||||
if (int64_t(*val) != 0) { cerr << "Expected int64_t(0) to be 0, was " << int64_t(*val) << endl; return false; }
|
||||
|
@ -988,9 +988,8 @@ namespace dom_api_tests {
|
|||
bool boolean_values_exception() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
string json(R"([ true, false ])");
|
||||
document::parser parser;
|
||||
document::array array = parser.parse(json).as_array();
|
||||
auto val = array.begin();
|
||||
dom::parser parser;
|
||||
auto val = parser.parse(json).as_array().begin();
|
||||
|
||||
if (bool(*val) != true) { cerr << "Expected bool(true) to be true, was " << bool(*val) << endl; return false; }
|
||||
++val;
|
||||
|
@ -1001,9 +1000,8 @@ namespace dom_api_tests {
|
|||
bool null_value_exception() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
string json(R"([ null ])");
|
||||
document::parser parser;
|
||||
document::array array = parser.parse(json).as_array();
|
||||
auto val = array.begin();
|
||||
dom::parser parser;
|
||||
auto val = parser.parse(json).as_array().begin();
|
||||
|
||||
if (!(*val).is_null()) { cerr << "Expected null to be null!" << endl; return false; }
|
||||
return true;
|
||||
|
@ -1012,8 +1010,8 @@ namespace dom_api_tests {
|
|||
bool document_object_index_exception() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
string json(R"({ "a": 1, "b": 2, "c": 3})");
|
||||
document::parser parser;
|
||||
document::element doc = parser.parse(json);
|
||||
dom::parser parser;
|
||||
element doc = parser.parse(json);
|
||||
if (uint64_t(doc["a"]) != 1) { cerr << "Expected uint64_t(doc[\"a\"]) to be 1, was " << uint64_t(doc["a"]) << endl; return false; }
|
||||
return true;
|
||||
}
|
||||
|
@ -1021,8 +1019,8 @@ namespace dom_api_tests {
|
|||
bool object_index_exception() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
string json(R"({ "obj": { "a": 1, "b": 2, "c": 3 } })");
|
||||
document::parser parser;
|
||||
document::object obj = parser.parse(json)["obj"];
|
||||
dom::parser parser;
|
||||
object obj = parser.parse(json)["obj"];
|
||||
if (uint64_t(obj["a"]) != 1) { cerr << "Expected uint64_t(doc[\"a\"]) to be 1, was " << uint64_t(obj["a"]) << endl; return false; }
|
||||
return true;
|
||||
}
|
||||
|
@ -1030,8 +1028,8 @@ namespace dom_api_tests {
|
|||
bool twitter_count_exception() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
// Prints the number of results in twitter.json
|
||||
document::parser parser;
|
||||
document::element doc = parser.load(JSON_TEST_PATH);
|
||||
dom::parser parser;
|
||||
element doc = parser.load(JSON_TEST_PATH);
|
||||
uint64_t result_count = doc["search_metadata"]["count"];
|
||||
if (result_count != 100) { cerr << "Expected twitter.json[metadata_count][count] = 100, got " << result_count << endl; return false; }
|
||||
return true;
|
||||
|
@ -1041,10 +1039,10 @@ namespace dom_api_tests {
|
|||
std::cout << "Running " << __func__ << std::endl;
|
||||
// Print users with a default profile.
|
||||
set<string_view> default_users;
|
||||
document::parser parser;
|
||||
document::element doc = parser.load(JSON_TEST_PATH);
|
||||
for (document::object tweet : doc["statuses"].as_array()) {
|
||||
document::object user = tweet["user"];
|
||||
dom::parser parser;
|
||||
element doc = parser.load(JSON_TEST_PATH);
|
||||
for (object tweet : doc["statuses"].as_array()) {
|
||||
object user = tweet["user"];
|
||||
if (user["default_profile"]) {
|
||||
default_users.insert(user["screen_name"]);
|
||||
}
|
||||
|
@ -1057,12 +1055,12 @@ namespace dom_api_tests {
|
|||
std::cout << "Running " << __func__ << std::endl;
|
||||
// Print image names and sizes
|
||||
set<pair<uint64_t, uint64_t>> image_sizes;
|
||||
document::parser parser;
|
||||
document::element doc = parser.load(JSON_TEST_PATH);
|
||||
for (document::object tweet : doc["statuses"].as_array()) {
|
||||
dom::parser parser;
|
||||
element doc = parser.load(JSON_TEST_PATH);
|
||||
for (object tweet : doc["statuses"].as_array()) {
|
||||
auto [media, not_found] = tweet["entities"]["media"];
|
||||
if (!not_found) {
|
||||
for (document::object image : media.as_array()) {
|
||||
for (object image : media.as_array()) {
|
||||
for (auto [key, size] : image["sizes"].as_object()) {
|
||||
image_sizes.insert(make_pair(size["w"], size["h"]));
|
||||
}
|
||||
|
@ -1108,8 +1106,9 @@ namespace dom_api_tests {
|
|||
|
||||
namespace format_tests {
|
||||
using namespace simdjson;
|
||||
using namespace simdjson::dom;
|
||||
using namespace std;
|
||||
const padded_string DOCUMENT(string(R"({ "foo" : 1, "bar" : [ 1, 2, 3 ], "baz": { "a": 1, "b": 2, "c": 3 } })"));
|
||||
const padded_string DOCUMENT = R"({ "foo" : 1, "bar" : [ 1, 2, 3 ], "baz": { "a": 1, "b": 2, "c": 3 } })"_padded;
|
||||
const string MINIFIED(R"({"foo":1,"bar":[1,2,3],"baz":{"a":1,"b":2,"c":3}})");
|
||||
bool assert_minified(ostringstream &actual, const std::string &expected=MINIFIED) {
|
||||
if (actual.str() != expected) {
|
||||
|
@ -1123,7 +1122,7 @@ namespace format_tests {
|
|||
|
||||
bool print_parser_parse() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
auto [doc, error] = parser.parse(DOCUMENT);
|
||||
if (error) { cerr << error << endl; return false; }
|
||||
ostringstream s;
|
||||
|
@ -1132,7 +1131,7 @@ namespace format_tests {
|
|||
}
|
||||
bool print_minify_parser_parse() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
auto [doc, error] = parser.parse(DOCUMENT);
|
||||
if (error) { cerr << error << endl; return false; }
|
||||
ostringstream s;
|
||||
|
@ -1142,7 +1141,7 @@ namespace format_tests {
|
|||
|
||||
bool print_element() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
auto [value, error] = parser.parse(DOCUMENT)["foo"];
|
||||
ostringstream s;
|
||||
s << value;
|
||||
|
@ -1150,7 +1149,7 @@ namespace format_tests {
|
|||
}
|
||||
bool print_minify_element() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
auto [value, error] = parser.parse(DOCUMENT)["foo"];
|
||||
ostringstream s;
|
||||
s << minify(value);
|
||||
|
@ -1159,7 +1158,7 @@ namespace format_tests {
|
|||
|
||||
bool print_array() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
auto [value, error] = parser.parse(DOCUMENT)["bar"].as_array();
|
||||
ostringstream s;
|
||||
s << value;
|
||||
|
@ -1167,7 +1166,7 @@ namespace format_tests {
|
|||
}
|
||||
bool print_minify_array() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
auto [value, error] = parser.parse(DOCUMENT)["bar"].as_array();
|
||||
ostringstream s;
|
||||
s << minify(value);
|
||||
|
@ -1176,7 +1175,7 @@ namespace format_tests {
|
|||
|
||||
bool print_object() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
auto [value, error] = parser.parse(DOCUMENT)["baz"].as_object();
|
||||
ostringstream s;
|
||||
s << value;
|
||||
|
@ -1184,7 +1183,7 @@ namespace format_tests {
|
|||
}
|
||||
bool print_minify_object() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
auto [value, error] = parser.parse(DOCUMENT)["baz"].as_object();
|
||||
ostringstream s;
|
||||
s << minify(value);
|
||||
|
@ -1195,7 +1194,7 @@ namespace format_tests {
|
|||
|
||||
bool print_parser_parse_exception() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
if (!parser.allocate_capacity(DOCUMENT.length())) { cerr << "Couldn't allocate!" << endl; return false; }
|
||||
ostringstream s;
|
||||
s << parser.parse(DOCUMENT);
|
||||
|
@ -1203,7 +1202,7 @@ namespace format_tests {
|
|||
}
|
||||
bool print_minify_parser_parse_exception() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
if (!parser.allocate_capacity(DOCUMENT.length())) { cerr << "Couldn't allocate!" << endl; return false; }
|
||||
ostringstream s;
|
||||
s << minify(parser.parse(DOCUMENT));
|
||||
|
@ -1212,16 +1211,16 @@ namespace format_tests {
|
|||
|
||||
bool print_element_result_exception() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
document::parser parser;
|
||||
document::element doc = parser.parse(DOCUMENT);
|
||||
dom::parser parser;
|
||||
element doc = parser.parse(DOCUMENT);
|
||||
ostringstream s;
|
||||
s << doc["foo"];
|
||||
return assert_minified(s, "1");
|
||||
}
|
||||
bool print_minify_element_result_exception() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
document::parser parser;
|
||||
document::element doc = parser.parse(DOCUMENT);
|
||||
dom::parser parser;
|
||||
element doc = parser.parse(DOCUMENT);
|
||||
ostringstream s;
|
||||
s << minify(doc["foo"]);
|
||||
return assert_minified(s, "1");
|
||||
|
@ -1229,18 +1228,18 @@ namespace format_tests {
|
|||
|
||||
bool print_element_exception() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
document::parser parser;
|
||||
document::element doc = parser.parse(DOCUMENT);
|
||||
document::element value = doc["foo"];
|
||||
dom::parser parser;
|
||||
element doc = parser.parse(DOCUMENT);
|
||||
element value = doc["foo"];
|
||||
ostringstream s;
|
||||
s << value;
|
||||
return assert_minified(s, "1");
|
||||
}
|
||||
bool print_minify_element_exception() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
document::parser parser;
|
||||
document::element doc = parser.parse(DOCUMENT);
|
||||
document::element value = doc["foo"];
|
||||
dom::parser parser;
|
||||
element doc = parser.parse(DOCUMENT);
|
||||
element value = doc["foo"];
|
||||
ostringstream s;
|
||||
s << minify(value);
|
||||
return assert_minified(s, "1");
|
||||
|
@ -1248,16 +1247,16 @@ namespace format_tests {
|
|||
|
||||
bool print_array_result_exception() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
document::parser parser;
|
||||
document::element doc = parser.parse(DOCUMENT);
|
||||
dom::parser parser;
|
||||
element doc = parser.parse(DOCUMENT);
|
||||
ostringstream s;
|
||||
s << doc["bar"].as_array();
|
||||
return assert_minified(s, "[1,2,3]");
|
||||
}
|
||||
bool print_minify_array_result_exception() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
document::parser parser;
|
||||
document::element doc = parser.parse(DOCUMENT);
|
||||
dom::parser parser;
|
||||
element doc = parser.parse(DOCUMENT);
|
||||
ostringstream s;
|
||||
s << minify(doc["bar"].as_array());
|
||||
return assert_minified(s, "[1,2,3]");
|
||||
|
@ -1265,16 +1264,16 @@ namespace format_tests {
|
|||
|
||||
bool print_object_result_exception() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
document::parser parser;
|
||||
document::element doc = parser.parse(DOCUMENT);
|
||||
dom::parser parser;
|
||||
element doc = parser.parse(DOCUMENT);
|
||||
ostringstream s;
|
||||
s << doc["baz"].as_object();
|
||||
return assert_minified(s, R"({"a":1,"b":2,"c":3})");
|
||||
}
|
||||
bool print_minify_object_result_exception() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
document::parser parser;
|
||||
document::element doc = parser.parse(DOCUMENT);
|
||||
dom::parser parser;
|
||||
element doc = parser.parse(DOCUMENT);
|
||||
ostringstream s;
|
||||
s << minify(doc["baz"].as_object());
|
||||
return assert_minified(s, R"({"a":1,"b":2,"c":3})");
|
||||
|
@ -1282,37 +1281,31 @@ namespace format_tests {
|
|||
|
||||
bool print_array_exception() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
document::parser parser;
|
||||
document::element doc = parser.parse(DOCUMENT);
|
||||
document::array value = doc["bar"];
|
||||
dom::parser parser;
|
||||
ostringstream s;
|
||||
s << value;
|
||||
s << parser.parse(DOCUMENT)["bar"];
|
||||
return assert_minified(s, "[1,2,3]");
|
||||
}
|
||||
bool print_minify_array_exception() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
document::parser parser;
|
||||
document::element doc = parser.parse(DOCUMENT);
|
||||
document::array value = doc["bar"];
|
||||
dom::parser parser;
|
||||
ostringstream s;
|
||||
s << minify(value);
|
||||
s << minify(parser.parse(DOCUMENT)["bar"]);
|
||||
return assert_minified(s, "[1,2,3]");
|
||||
}
|
||||
|
||||
bool print_object_exception() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
document::parser parser;
|
||||
document::element doc = parser.parse(DOCUMENT);
|
||||
document::object value = doc["baz"];
|
||||
dom::parser parser;
|
||||
ostringstream s;
|
||||
s << value;
|
||||
s << parser.parse(DOCUMENT)["baz"];
|
||||
return assert_minified(s, R"({"a":1,"b":2,"c":3})");
|
||||
}
|
||||
bool print_minify_object_exception() {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
document::parser parser;
|
||||
document::element doc = parser.parse(DOCUMENT);
|
||||
document::object value = doc["baz"];
|
||||
dom::parser parser;
|
||||
element doc = parser.parse(DOCUMENT);
|
||||
object value = doc["baz"];
|
||||
ostringstream s;
|
||||
s << minify(value);
|
||||
return assert_minified(s, R"({"a":1,"b":2,"c":3})");
|
||||
|
|
|
@ -26,14 +26,14 @@ namespace parser_load {
|
|||
const char * NONEXISTENT_FILE = "this_file_does_not_exit.json";
|
||||
bool parser_load_capacity() {
|
||||
TEST_START();
|
||||
document::parser parser(1); // 1 byte max capacity
|
||||
dom::parser parser(1); // 1 byte max capacity
|
||||
auto [doc, error] = parser.load(JSON_TEST_PATH);
|
||||
ASSERT_ERROR(error, CAPACITY);
|
||||
TEST_SUCCEED();
|
||||
}
|
||||
bool parser_load_many_capacity() {
|
||||
TEST_START();
|
||||
document::parser parser(1); // 1 byte max capacity
|
||||
dom::parser parser(1); // 1 byte max capacity
|
||||
for (auto [doc, error] : parser.load_many(JSON_TEST_PATH)) {
|
||||
ASSERT_ERROR(error, CAPACITY);
|
||||
TEST_SUCCEED();
|
||||
|
@ -43,14 +43,14 @@ namespace parser_load {
|
|||
|
||||
bool parser_load_nonexistent() {
|
||||
TEST_START();
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
auto [doc, error] = parser.load(NONEXISTENT_FILE);
|
||||
ASSERT_ERROR(error, IO_ERROR);
|
||||
TEST_SUCCEED();
|
||||
}
|
||||
bool parser_load_many_nonexistent() {
|
||||
TEST_START();
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
for (auto [doc, error] : parser.load_many(NONEXISTENT_FILE)) {
|
||||
ASSERT_ERROR(error, IO_ERROR);
|
||||
TEST_SUCCEED();
|
||||
|
@ -66,14 +66,14 @@ namespace parser_load {
|
|||
|
||||
bool parser_load_chain() {
|
||||
TEST_START();
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
auto [val, error] = parser.load(NONEXISTENT_FILE)["foo"].as_uint64_t();
|
||||
ASSERT_ERROR(error, IO_ERROR);
|
||||
TEST_SUCCEED();
|
||||
}
|
||||
bool parser_load_many_chain() {
|
||||
TEST_START();
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
for (auto doc : parser.load_many(NONEXISTENT_FILE)) {
|
||||
auto [val, error] = doc["foo"].as_uint64_t();
|
||||
ASSERT_ERROR(error, IO_ERROR);
|
||||
|
|
|
@ -32,7 +32,7 @@ template <typename T>
|
|||
static void parse_and_validate(const std::string src, T expected) {
|
||||
std::cout << "src: " << src << ", ";
|
||||
const padded_string pstr{src};
|
||||
simdjson::document::parser parser;
|
||||
simdjson::dom::parser parser;
|
||||
|
||||
bool result;
|
||||
if constexpr (std::is_same<int64_t, T>::value) {
|
||||
|
@ -54,7 +54,7 @@ static void parse_and_validate(const std::string src, T expected) {
|
|||
static bool parse_and_check_signed(const std::string src) {
|
||||
std::cout << "src: " << src << ", expecting signed" << std::endl;
|
||||
const padded_string pstr{src};
|
||||
simdjson::document::parser parser;
|
||||
simdjson::dom::parser parser;
|
||||
auto [value, error] = parser.parse(pstr).as_object()["key"];
|
||||
if (error) { std::cerr << error << std::endl; abort(); }
|
||||
return value.is_integer() && value.is_number();
|
||||
|
@ -63,7 +63,7 @@ static bool parse_and_check_signed(const std::string src) {
|
|||
static bool parse_and_check_unsigned(const std::string src) {
|
||||
std::cout << "src: " << src << ", expecting signed" << std::endl;
|
||||
const padded_string pstr{src};
|
||||
simdjson::document::parser parser;
|
||||
simdjson::dom::parser parser;
|
||||
auto [value, error] = parser.parse(pstr).as_object()["key"];
|
||||
if (error) { std::cerr << error << std::endl; abort(); }
|
||||
return value.is_unsigned_integer() && value.is_number();
|
||||
|
|
|
@ -69,7 +69,7 @@ bool validate(const char *dirname) {
|
|||
std::cerr << "Could not load the file " << fullpath << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
simdjson::document::parser parser;
|
||||
simdjson::dom::parser parser;
|
||||
auto [doc, errorcode] = parser.parse(p);
|
||||
++how_many;
|
||||
printf("%s\n", errorcode == simdjson::error_code::SUCCESS ? "ok" : "invalid");
|
||||
|
|
|
@ -178,7 +178,7 @@ bool validate(const char *dirname) {
|
|||
int_count = 0;
|
||||
invalid_count = 0;
|
||||
total_count += float_count + int_count + invalid_count;
|
||||
simdjson::document::parser parser;
|
||||
simdjson::dom::parser parser;
|
||||
auto [doc, err] = parser.parse(p);
|
||||
bool isok = (err == simdjson::error_code::SUCCESS);
|
||||
if (int_count + float_count + invalid_count > 0) {
|
||||
|
|
|
@ -77,7 +77,7 @@ bool validate(const char *dirname) {
|
|||
/* The actual test*/
|
||||
auto [json, error] = simdjson::padded_string::load(fullpath);
|
||||
if (!error) {
|
||||
simdjson::document::parser parser;
|
||||
simdjson::dom::parser parser;
|
||||
|
||||
++how_many;
|
||||
for (auto result : parser.parse_many(json)) {
|
||||
|
|
|
@ -34,7 +34,7 @@ const padded_string TEST_JSON = R"(
|
|||
|
||||
bool json_pointer_success_test(const char *json_pointer, std::string_view expected_value) {
|
||||
std::cout << "Running successful JSON pointer test '" << json_pointer << "' ..." << std::endl;
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
auto [value, error] = parser.parse(TEST_JSON)[json_pointer].as_string();
|
||||
if (error) { std::cerr << "Unexpected Error: " << error << std::endl; return false; }
|
||||
ASSERT(value == expected_value);
|
||||
|
@ -43,7 +43,7 @@ bool json_pointer_success_test(const char *json_pointer, std::string_view expect
|
|||
|
||||
bool json_pointer_success_test(const char *json_pointer) {
|
||||
std::cout << "Running successful JSON pointer test '" << json_pointer << "' ..." << std::endl;
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
auto [value, error] = parser.parse(TEST_JSON)[json_pointer];
|
||||
if (error) { std::cerr << "Unexpected Error: " << error << std::endl; return false; }
|
||||
return true;
|
||||
|
@ -52,7 +52,7 @@ bool json_pointer_success_test(const char *json_pointer) {
|
|||
|
||||
bool json_pointer_failure_test(const char *json_pointer, error_code expected_failure_test) {
|
||||
std::cout << "Running invalid JSON pointer test '" << json_pointer << "' ..." << std::endl;
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
auto [value, error] = parser.parse(TEST_JSON)[json_pointer];
|
||||
ASSERT(error == expected_failure_test);
|
||||
return true;
|
||||
|
|
|
@ -7,7 +7,7 @@ void parser_parse_error_code() {
|
|||
cout << __func__ << endl;
|
||||
|
||||
// Allocate a parser big enough for all files
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
|
||||
// Read files with the parser, one by one
|
||||
for (padded_string json : { string("[1, 2, 3]"), string("true"), string("[ true, false ]") }) {
|
||||
|
@ -24,7 +24,7 @@ void parser_parse_many_error_code() {
|
|||
// Read files with the parser
|
||||
auto json = "[1, 2, 3] true [ true, false ]"_padded;
|
||||
cout << "Parsing " << json.data() << " ..." << endl;
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
for (auto [doc, error] : parser.parse_many(json)) {
|
||||
if (error) { cerr << "Error: " << error << endl; exit(1); }
|
||||
cout << doc << endl;
|
||||
|
@ -36,7 +36,7 @@ void parser_parse_max_capacity() {
|
|||
|
||||
int argc = 2;
|
||||
padded_string argv[] { string("[1,2,3]"), string("true") };
|
||||
document::parser parser(1024*1024); // Set max capacity to 1MB
|
||||
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); }
|
||||
|
@ -50,7 +50,7 @@ void parser_parse_fixed_capacity() {
|
|||
|
||||
int argc = 2;
|
||||
padded_string argv[] { string("[1,2,3]"), string("true") };
|
||||
document::parser parser(0); // This parser is not allowed to auto-allocate
|
||||
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++) {
|
||||
|
@ -67,7 +67,7 @@ void parser_parse_padded_string() {
|
|||
cout << __func__ << endl;
|
||||
|
||||
auto json = "[ 1, 2, 3 ]"_padded;
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
cout << parser.parse(json) << endl;
|
||||
}
|
||||
|
||||
|
@ -75,7 +75,7 @@ void parser_parse_get_corpus() {
|
|||
cout << __func__ << endl;
|
||||
|
||||
auto json = get_corpus("jsonexamples/small/demo.json");
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
cout << parser.parse(json) << endl;
|
||||
}
|
||||
|
||||
|
@ -83,7 +83,7 @@ void parser_parse_exception() {
|
|||
cout << __func__ << endl;
|
||||
|
||||
// Allocate a parser big enough for all files
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
|
||||
// Read files with the parser, one by one
|
||||
for (padded_string json : { string("[1, 2, 3]"), string("true"), string("[ true, false ]") }) {
|
||||
|
@ -98,8 +98,8 @@ void parser_parse_many_exception() {
|
|||
// Read files with the parser
|
||||
auto json = "[1, 2, 3] true [ true, false ]"_padded;
|
||||
cout << "Parsing " << json.data() << " ..." << endl;
|
||||
document::parser parser;
|
||||
for (const document::element doc : parser.parse_many(json)) {
|
||||
dom::parser parser;
|
||||
for (const dom::element doc : parser.parse_many(json)) {
|
||||
cout << doc << endl;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ using namespace simdjson;
|
|||
int main() {
|
||||
const char *filename = JSON_TEST_PATH;
|
||||
padded_string p = get_corpus(filename);
|
||||
document::parser parser;
|
||||
dom::parser parser;
|
||||
auto [doc, error] = parser.parse(p);
|
||||
if(error) {
|
||||
std::cerr << error << std::endl;
|
||||
|
|
|
@ -347,7 +347,7 @@ bool validate(const char *dirname) {
|
|||
good_string = 0;
|
||||
total_string_length = 0;
|
||||
empty_string = 0;
|
||||
simdjson::document::parser parser;
|
||||
simdjson::dom::parser parser;
|
||||
auto [doc, err] = parser.parse(p);
|
||||
bool isok = (err == simdjson::error_code::SUCCESS);
|
||||
free(big_buffer);
|
||||
|
|
|
@ -34,7 +34,7 @@ int main(int argc, char *argv[]) {
|
|||
std::cerr << "warning: ignoring everything after " << argv[optind + 1]
|
||||
<< std::endl;
|
||||
}
|
||||
simdjson::document::parser parser;
|
||||
simdjson::dom::parser parser;
|
||||
auto [doc, error] = parser.load(filename); // do the parsing, return false on error
|
||||
if (error != simdjson::SUCCESS) {
|
||||
std::cerr << " Parsing failed. Error is '" << simdjson::error_message(error)
|
||||
|
|
|
@ -19,7 +19,7 @@ int main(int argc, char *argv[]) {
|
|||
}
|
||||
|
||||
const char *filename = argv[1];
|
||||
simdjson::document::parser parser;
|
||||
simdjson::dom::parser parser;
|
||||
auto [doc, error] = parser.load(filename);
|
||||
if (error) { std::cerr << "Error parsing " << filename << ": " << error << std::endl; }
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ bool is_ascii(const std::string_view &v) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void recurse(simdjson::document::element element, stat_t &s, size_t depth) {
|
||||
void recurse(simdjson::dom::element element, stat_t &s, size_t depth) {
|
||||
if (depth > s.maximum_depth) {
|
||||
s.maximum_depth = depth;
|
||||
}
|
||||
|
@ -125,7 +125,7 @@ void recurse(simdjson::document::element element, stat_t &s, size_t depth) {
|
|||
|
||||
stat_t simdjson_compute_stats(const simdjson::padded_string &p) {
|
||||
stat_t s{};
|
||||
simdjson::document::parser parser;
|
||||
simdjson::dom::parser parser;
|
||||
auto [doc, error] = parser.parse(p);
|
||||
if (error) {
|
||||
s.valid = false;
|
||||
|
|
Loading…
Reference in New Issue